|
Project
|
SubGit
|
|
Priority
|
Normal |
|
Type
|
Bug |
|
State
|
Fixed |
|
Assignee
|
Semyon Vadishev |
|
Subsystem
|
Translator Core |
|
Affected versions
|
Miai EAP5 (build 1096) |
|
Fix versions
|
1.0.0 (build 1696), Miai EAP6 (build 1381) |
|
Fixed in build
|
No Fixed in build
|
At this moment you have:
REMOTE_SVN_REPO — original svn repository
REMOTE_GIT_REPO — git repository synchronized
LOCAL_GIT_REPO — git repository you've cloned from REMOTE_GIT_REPO.
Everything is up-to-date, i.e. every svn revision represents corresponding git commit and vice versa.
You have some commits which present in LOCAL_GIT_REPO and REMOTE_GIT_REPO, but there are no corresponding revisions in REMOTE_SVN_REPO, since synchronization didn't start due to hooks misconfiguration.
Probably, you also have some revisions in REMOTE_SVN_REPO which are not yet synchronized with REMOTE_GIT_REPOSITORY, so they don't present in LOCAL_GIT_REPO.
After that your REMOTE_GIT_REPO contains commits converted from those revisions committed into REMOTE_SVN_REPO after the very first 'subgit install'.
At this moment you have REMOTE_SVN_REPO and REMOTE_GIT_REPO up-to-date, but REMOTE_GIT_REPO and LOCAL_GIT_REPO are not up-to-date.
Your LOCAL_GIT_REPO contains those commits which are neither in REMOTE_GIT_REPO nor in REMOTE_SVN_REPO, at the same time REMOTE_GIT_REPO has some commits converted from those revisions committed after the very first install, and these commits are not in LOCAL_GIT_REPO. In git terms you have a diverged history.
When you run 'git pull', git created a merge commit with the "merge from master" message. This situation is typical when one uses 'git pull' instead of 'git pull –rebase'.
So, what SubGit sees: there is a merge commit referenced by 'master' ref, it has two parents from REMOTE_GIT_REPO and LOCAL_GIT_REPO. SubGit has nothing to do but send first parent into ^/trunk, which correspondes to master branch in Git. The second parent goes into a artificial branch, or "shelf" as we call it, so you get this temporary branch ^/shelves/myshelf.
We introduced shelves exactly for this case — when we can say nothing about what branch these commits belongs to.
That's pretty strange, ^/shelves/mushelf exists only for those revisions when SubGit was translating the diverged history. SubGit always deletes all the shelves as soon as it converts the merge commit which joins the diverged commits.
From the log you've provided I can say that translation was in progress, hence SubGit should not allow you to commit the branch deletion. Did this commit actually happen. Is there corresponding revision entry in 'svn log -v ^/' output?
If I'm right, the failure you hit is not related to the deleted shelf, but is something more generic.
I have also disabled shelves mapping by using
shelves = shelves/*
As the shelves configuration.
'subgit install' must exit with error if you have no git.*.shelves config options.
As I described in my previous comment:
SubGit creates shelves only when it fails to find a good name for some branch in Git.
shelves = shelves/*
apping, most likely it will explode in a bad way if it ever tries to actually create a shelve.
I'm sorry, I misunderstood that. "shelves = shelves/*" is a just a shortcut for "shelves = shelves/*:refs/shelves/*", so technically you'll get the same behavior with such configuration.
Will you consider a conf switch to disable shelves entirely ?
I guess i could be extremely careful with my git usage but i would much prefer having sugit block any shelve creating attempt :( event at the cost of having to clone my local repo again and manually recover my changes.
AFAIU, you suggest the following:
1. In case some user pushes a piece of Git history with shelves to be created in svn, we reject such push operation and asks user to linearize the history.
2. If SubGit fails to determine a branch for one of parents of a merge commit, throw away the history of this parent.
Formerly we had discussion on these issues and decided that the shelves approach has much more benefits comparing to its alternatives. So, we decided to hold this way. Sure, we understand that a special branches namespace may confuse some users, but we believe that proper usage of rebase instead of merge fix the problem in general.
Here is the pattern we use to detect such merge commits:
merge (remote-tracking )?branch ['"]?({branch}/)*({branch})['"]? of .+
I guess i could be extremely careful with my git usage but i would much prefer having sugit block any shelve creating attempt :( event at the cost of having to clone my local repo again and manually recover my changes.
I doubt we'll do that in near future. But if at some moment we will decide to do that, we'll stick the option 2 from my previous comment:
May I ask you what exactly disturbs you? Having shelves directory in repository root or having shelves in log output?
We have plans to delete shelves directory every time it's empty. This way, most of the time repository root won't have this directory, it will present only for those revisions when one of shelves actually was added by SubGit.
Be able to use the full git power to create branches merge them and share them with some other advanced users, while keeping it completly transparent for the svn users.
That is why I configured my namespace so that branches from svn are a subset of git branches (see SGT-436). I want to be able to create branches (feature branches most likely) in git, push them in the central repository to be able to share them easily with other developers and NOT have them appear in SVN at all, then merge them in master or in one of the svn branch and push that to svn. On the svn side I would like it to appear as a normal commit, possibly with a weird message, but I don't want to replicate the full branch
If I want the feature branch history, either I branch it off to the svn namespace and push it on the server where it will be published in svn, or I rebase it onto master and push that. In the rebase case, I still don't want the git feature branch to be pushed to svn.
I am not sure the regex pre commit hook is a solution actually, and if you are able to determine which branch to shelve, you are also able to determine which history to drop : the history for the branch you would have shleved, the history for the git ref which does not exist in svn.
edit
After pondering this some more:
It's really hard to understand, what branch to throw away. User may wonder how that comes that they did a bunch of commits but in Subversion history they created has squashed into a single revision.
Isn't this is exactly what happens in git history ... if you only consider the branch which received the merge you will only see merge branch 'whatever' and not the commit history, unless you did a rebase ...
Only if the ref created is mapped in the svn repo, and then yes it makes sense to translate the corresponding commits, but not before that ...
I got your point, thank you.
The use case you're describing is definitely interesting. But there are another not less important scenarios we have to think about:
Just imagine you're translating the history of 10 000 git commits into Subversion. The first one is a merge commit, the only reference available refers to this commit. And, yes, this is something one can find in the wild github jungles.
So, you have to decide which part of the history won't be ever available to any svn user. That means, say, 5 000 commits of history will disappear completely from Subversion. And what if soon someone adds a tag on the commit you just dropped?
As I already mentioned, in our team we discussed the behavior you're describing. At the end of the day we found that using additional ^/shelves/* namespace significantly decreases the possible risks for SubGit users. And all that by the price most svn users will never notice.
I mean, really, for an average Subversion user the difference between the current behavior and your suggestion is just a single line in svn:mergeinfo property one gets on svn update.
And I'm not saying we will never implement what you've suggested. Probably, we will. But it's definitely not for SubGit 1.0. We need to gather more feedback, understand which edge cases we have to consider, etc.
I doubt that.
$ git log master
commit 27fcd3db59b0fbeea27bb25fd39a81cc83111b21
Merge: ae5171a c498aab
Merge branch 'foo' into 'master'
commit ae5171a6e2fb5ce358c48ea368f27d7e61624783
Commit on master branch.
commit c498aab18c7315b445417304bb99b51d3e410274
Commit on foo branch.
commit bc65b202d094a3bf111fb076c55e75f7e2e7af95
initial
Yes, that makes sense. I put some random thoughts on every option there.
I will open another bug somewhere since the repo sync was lost when I deleted the shelve and the shelves root from svn when I shouldn't have been able to.
As far as I remember I pushed from git then, svn updated on the other side, then visually checked the svn repo. I tried to get some info on what shelves where then I removed the inner folder then the shelve root (which is why there are 2 commits) and didn't get any errors. I noticed the problem after cloning fresh starting to work on it and not getting one of the modifications from a co-worker ... that's when I saw the sync error zip file.