开发者

What could cause "number of commits ahead" to change after rebasing?

开发者 https://www.devze.com 2023-02-11 18:28 出处:网络
Before rebasing a feature branch that I hadn\'t touched in a few weeks, it was 25 commits ahead of master. After rebasing, it is now 18 commits. There were several conflicts I had开发者_StackOverflow中

Before rebasing a feature branch that I hadn't touched in a few weeks, it was 25 commits ahead of master. After rebasing, it is now 18 commits. There were several conflicts I had开发者_StackOverflow中文版 to resolve along the way. Possibly exactly 7.

What could cause this number change? Cherry picks that were discovered along the way and turned into NOOP commits? The above mentioned conflict resolutions?


There are a few possible ways this could happen - this isn't an exhaustive list, but should give you the idea of how this can come about:

1. Cherry-picked commits

Firstly, you mention the possibility that commits from your branch had been cherry-picked into the upstream branch that you're rebasing onto: just to confirm this, git rebase will skip any such commits, which might account for some part of the discrepancy. There's more on that in VonC's answer to this question.

2. Conflicts resolved to exactly the upstream version

My initial suspicion was that what happened was that when you were rebasing and saw conflicts, you always resolved them by choosing the upstream version rather than your changes. (If this doesn't ring a bell, then my suspicion is probably completely wrong :)) If there were no other non-conflicting changes introduced by that commit, then what your conflict resolution will have done is to just make the tree the same as it was before it tried to apply the patch from your change, so there's nothing to commit.

Unfortunately, the prompts that git gives you when this happens can be rather confusing. Here's an example of what you'll see with git 1.7.1. First, commit a change that's going to conflict with one that's not yet been merged from origin/master:

$ git commit
[master 1efa20f] Add a change designed to conflict
 1 files changed, 1 insertions(+), 1 deletions(-)

... now start the rebase:

$ git rebase origin/master 
First, rewinding head to replay your work on top of it...
Applying: Add a change designed to conflict
Using index info to reconstruct a base tree...
Falling back to patching base and 3-way merge...
Auto-merging src-plugins/3D_Viewer/ij3d/Image3DUniverse.java
CONFLICT (content): Merge conflict in src-plugins/3D_Viewer/ij3d/Image3DUniverse.java
Failed to merge in the changes.
Patch failed at 0001 Add a change designed to conflict

When you have resolved this problem run "git rebase --continue".
If you would prefer to skip this patch, instead run "git rebase --skip".
To restore the original branch and stop rebasing run "git rebase --abort".

Look at what the conflict was:

$  git diff
diff --cc src-plugins/3D_Viewer/ij3d/Image3DUniverse.java
index 36ec046,f4841ec..0000000
--- a/src-plugins/3D_Viewer/ij3d/Image3DUniverse.java
+++ b/src-plugins/3D_Viewer/ij3d/Image3DUniverse.java
@@@ -264,7 -264,7 +264,11 @@@ public class Image3DUniverse extends De
        public void cleanup() {
                timeline.pause();
                removeAllContents();
++<<<<<<< HEAD
 +              contents.clear();
++=======
+               contents.clear(); // A change designed to conflict
++>>>>>>> Add a change designed to conflict
                universes.remove(this);
                adder.shutdownNow();
                executer.flush();

I've decided I like the version from upstream, so edit the file to resolve that:

$  vim src-plugins/3D_Viewer/ij3d/Image3DUniverse.java

Stage the resolution of that conflict:

$ git add src-plugins/3D_Viewer/ij3d/Image3DUniverse.java

Now try to continue with the rebase as usual:

$ git rebase --continue
Applying: Add a change designed to conflict
No changes - did you forget to use 'git add'?

When you have resolved this problem run "git rebase --continue".
If you would prefer to skip this patch, instead run "git rebase --skip".
To restore the original branch and stop rebasing run "git rebase --abort".

I think that in more recent versions of git, it suggests that you might have just resolved the commit to what was there already, and that you should consider is doing git rebase --skip. However, typically people work out that that's the only way out of this situation anyway, so:

$  git rebase --skip
HEAD is now at f3a2de3 3D Viewer: Avoid NPE when closing the viewer window.
Nothing to do.

That commit will now not appear in git log.

3. Merge commits

You mention in the comments below that you saw several merge commits when examining the two branches afterwards - this could also be a cause of missing commits, since git rebase by default ignores any merge commits when it prepares its list of commits to reapply onto upstream.


To expand on Jefromi's comment a bit, you could compare the ouput of git log --pretty=oneline -n18 <branch> with git log --pretty=oneline -n25 <branch>@{1} and see which commits went missing. As he mentioned, you might need to use git reflog a bit if you've done some work since to determine which entry is your pre-rebase branch head.

0

精彩评论

暂无评论...
验证码 换一张
取 消