Hi all,
I've got an issue with some operations. It seems like git eats one of my commits (it's still in reflog, but in normal tree, it's unavailable).
What I did is:
checkout -b feature/....
(edit files and commit)
checkout master
merge --no-ff --no-commit feature/...
(edit some files, change versions, changelog)
commit
Now I've got the change committed in the branch and some more changes on the merge commit.
So before pushing to the main repo, I'd like to check if any other changes are there:
pull --rebase
Now my merge commit disappears completely along with the changes without any warning. I get the branch commits duplicated on top of master and the branch stays as it was.
That looks like a data loss bug to me since I can only recover a committed change from reflog and there are no warnings before that change goes away (using 1.7.4.1). Actually no changes were done in upstream in the meantime, so the rebase was not even needed.
Regards,
Stanisław Pitucha
Cloud Services
Hewlett Packard
Hi all,
I've got an issue with some operations. It seems like git eats one of my commits (it's still in reflog, but in normal tree, it's unavailable).
What I did is:
checkout -b feature/....
(edit files and commit)
checkout master
merge --no-ff --no-commit feature/...
(edit some files, change versions, changelog)
commit
Now I've got the change committed in the branch and some more changes on the merge commit.
So before pushing to the main repo, I'd like to check if any other changes are there:
pull --rebase
Now my merge commit disappears completely along with the changes without any warning. I get the branch commits duplicated on top of master and the branch stays as it was.
That looks like a data loss bug to me since I can only recover a committed change from reflog and there are no warnings before that change goes away (using 1.7.4.1). Actually no changes were done in upstream in the meantime, so the rebase was not even needed.
That is definitely not a bug.
"git pull --rebase" is (almost?) equal to "git fetch ; git rebase origin/master"
When you perform a rebase, at first your HEAD is rolled back to the commit before your changes, then it is fast-forwared to the remote HEAD (in your case, no fast-forward was made, because there were no remote changes); then your commits are applied one by one.
Of couse, when your commits are applied, they are applied like patches. That mean, that they are different from the original commits (at least, by the commit time). That causes the duplication.
And the merge commit "dissapeared", because it contained no changes, so the patch was empty, and there was nothing to reapply.
If the merge commit contained some changes, and it really was not applied during rebase, it is a bug, but more details will be needed, I think.
If you want to preserve your branch history, you should do "pull" without "rebase".
Kirill.
As mentioned in the original mail - the merge commit did have changes. Here's the log of reproducing it. The line containing "2" in changelog is gone from master after pull --rebase.
$ git init fake_upstream
Initialized empty Git repository in /tmp/fake_upstream/.git/
$ cd fake_upstream/
fake_upstream$ echo some_content > test
fake_upstream$ echo 1 > changelog
fake_upstream$ git add test changelog
fake_upstream$ git commit -m 'first commit'
[master (root-commit) b1b683d] first commit
2 files changed, 2 insertions(+), 0 deletions(-)
create mode 100644 changelog
create mode 100644 test
fake_upstream$ cd ..
$ git clone /tmp/fake_upstream/ disappearing_commit
Cloning into disappearing_commit...
done.
$ cd disappearing_commit/
disappearing_commit$ git checkout -b some-branch
Switched to a new branch 'some-branch'
disappearing_commit$ echo blah >> test
disappearing_commit$ git commit test -m 'branch modification'
[some-branch 528f166] branch modification
1 files changed, 1 insertions(+), 0 deletions(-)
disappearing_commit$ git checkout master
Switched to branch 'master'
disappearing_commit$ git merge --no-ff --no-commit some-branch
Automatic merge went well; stopped before committing as requested
disappearing_commit$ echo 2 >> changelog
disappearing_commit$ git add changelog
disappearing_commit$ git commit
[master e41e4c9] Merge branch 'some-branch'
disappearing_commit$ git show
commit e41e4c963a72528e3b2b5945ca419e19cdba1e4b
Merge: b1b683d 528f166
Author: Stanislaw Pitucha [off-list ref]
Date: Thu Nov 10 13:30:04 2011 +0000
Merge branch 'some-branch'
diff --cc changelog
index d00491f,d00491f..1191247
--- a/changelog+++ b/changelog
@@@ -1,1 -1,1 +1,2 @@@
1
++2
disappearing_commit$ git pull --rebase
First, rewinding head to replay your work on top of it...
Applying: branch modification
disappearing_commit$ git show
commit ef8f5e40db9fe7efbd4e493ff68b12327acde283
Author: Stanislaw Pitucha [off-list ref]
Date: Thu Nov 10 13:29:33 2011 +0000
branch modification
From: Johannes Sixt <hidden> Date: 2016-06-15 22:52:28
Am 11/10/2011 14:35, schrieb Pitucha, Stanislaw Izaak:
As mentioned in the original mail - the merge commit did have changes.
Here's the log of reproducing it. The line containing "2" in changelog
is gone from master after pull --rebase.
...
disappearing_commit$ git merge --no-ff --no-commit some-branch
Automatic merge went well; stopped before committing as requested
disappearing_commit$ echo 2 >> changelog
disappearing_commit$ git add changelog
disappearing_commit$ git commit
[master e41e4c9] Merge branch 'some-branch'
This is by design. Rebase does not rebase merge commits because it is
assumed that merge commits only do what their name implies - to merge
branches of a forked history. As such, they do not introduce their own
changes. Follow this rule, i.e., make your change in a separate non-merge
commit, and you are fine.
-- Hannes
From: Philippe Vaucher <hidden> Date: 2016-06-15 22:52:28
This is by design. Rebase does not rebase merge commits because it is
assumed that merge commits only do what their name implies - to merge
branches of a forked history. As such, they do not introduce their own
changes. Follow this rule, i.e., make your change in a separate non-merge
commit, and you are fine.
Doesn't this create a problem if you pull, resolve a conflit but do NOT
push, then pull --rebase some more commits later on? As I understand
it, the conflict resolution commit will be a merge commit and will be
thrown away by the git pull --rebase.
Philippe
From: Johannes Sixt <hidden> Date: 2016-06-15 22:52:28
Am 11/11/2011 10:50, schrieb Philippe Vaucher:
quoted
This is by design. Rebase does not rebase merge commits because it is
assumed that merge commits only do what their name implies - to merge
branches of a forked history. As such, they do not introduce their own
changes. Follow this rule, i.e., make your change in a separate non-merge
commit, and you are fine.
Doesn't this create a problem if you pull, resolve a conflit but do NOT
push, then pull --rebase some more commits later on? As I understand
it, the conflict resolution commit will be a merge commit and will be
thrown away by the git pull --rebase.
You are correct, but it is not a problem: During the rebase, the same
conflicts will arise as during the merge, and you will be forced to
resolve them before you can complete the rebase. Therefore, nothing will
be lost.
-- Hannes
From: Philippe Vaucher <hidden> Date: 2016-06-15 22:52:28
quoted
Doesn't this create a problem if you pull, resolve a conflit but do NOT
push, then pull --rebase some more commits later on? As I understand
it, the conflict resolution commit will be a merge commit and will be
thrown away by the git pull --rebase.
You are correct, but it is not a problem: During the rebase, the same
conflicts will arise as during the merge, and you will be forced to
resolve them before you can complete the rebase. Therefore, nothing will
be lost.
Doing the same conflict resolution twice is kinda irritating... but
ok, fair enough.
I guess when you resolve a conflict you're supposed to push to avoid this :)
Philippe