From: Lars Hjemli <hidden> Date: 2016-06-15 22:43:35
This new option forces all merges to create a "true" merge commit, i.e. a
commit with multiple parents.
Although a fast-forward would normally be The Right Thing, it isn't when the
branches to be merged originated in subversion and the merge commit will
be pushed back by means of 'git svn dcommit'. In these cases, a fast-
forward merge simply will not work.
Signed-off-by: Lars Hjemli <redacted>
---
Documentation/merge-options.txt | 4 ++++
git-merge.sh | 13 +++++++++++--
t/t6028-merge-up-to-date.sh | 25 +++++++++++++++++++++++++
3 files changed, 40 insertions(+), 2 deletions(-)
@@ -25,3 +25,7 @@ If there is no `-s` option, a built-in list of strategies is used instead (`git-merge-recursive` when merging a single head, `git-merge-octopus` otherwise).++--no-ff::+ Force the creation of a merge commit even when the merge would+ have resolved as a fast-forward operation.
@@ -444,7 +448,12 @@ done# auto resolved the merge cleanly.iftest''!="$result_tree"then-parents=$(gitshow-branch--independent"$head""$@"|sed-e's/^/-p /')+iftest$no_ff='t'+then+parents=$(gitrev-parse"$head""$@"|sed-e's/^/-p /')+else+parents=$(gitshow-branch--independent"$head""$@"|sed-e's/^/-p /')+firesult_commit=$(printf'%s\n'"$merge_msg"|gitcommit-tree$result_tree$parents)||exitfinish"$result_commit""Merge made by $wt_strategy."dropsave
From: Andreas Ericsson <hidden> Date: 2016-06-15 22:43:35
Lars Hjemli wrote:
This new option forces all merges to create a "true" merge commit, i.e. a
commit with multiple parents.
Although a fast-forward would normally be The Right Thing, it isn't when the
branches to be merged originated in subversion and the merge commit will
be pushed back by means of 'git svn dcommit'. In these cases, a fast-
forward merge simply will not work.
If there is no `-s` option, a built-in list of strategies
is used instead (`git-merge-recursive` when merging a single
head, `git-merge-octopus` otherwise).
+
+--no-ff::
+ Force the creation of a merge commit even when the merge would
+ have resolved as a fast-forward operation.
+ Although a fast-forward would normally be The Right Thing, it isn't when the
+ branches to be merged originated in subversion and the merge commit will
+ be pushed back by means of 'git svn dcommit'. In these cases, a fast-
+ forward merge simply will not work.
Otherwise someone will sit down and try to figure out why this is necessary.
I'm having trouble understanding why this is needed, but I'll take your word
for it ;-)
--
Andreas Ericsson andreas.ericsson@op5.se
OP5 AB www.op5.se
Tel: +46 8-230225 Fax: +46 8-230231
From: Lars Hjemli <hidden> Date: 2016-06-15 22:43:35
On 9/17/07, Andreas Ericsson [off-list ref] wrote:
Lars Hjemli wrote:
quoted
This new option forces all merges to create a "true" merge commit, i.e. a
commit with multiple parents.
Although a fast-forward would normally be The Right Thing, it isn't when the
branches to be merged originated in subversion and the merge commit will
be pushed back by means of 'git svn dcommit'. In these cases, a fast-
forward merge simply will not work.
If there is no `-s` option, a built-in list of strategies
is used instead (`git-merge-recursive` when merging a single
head, `git-merge-octopus` otherwise).
+
+--no-ff::
+ Force the creation of a merge commit even when the merge would
+ have resolved as a fast-forward operation.
+ Although a fast-forward would normally be The Right Thing, it isn't when the
+ branches to be merged originated in subversion and the merge commit will
+ be pushed back by means of 'git svn dcommit'. In these cases, a fast-
+ forward merge simply will not work.
Otherwise someone will sit down and try to figure out why this is necessary.
True.
I'm having trouble understanding why this is needed, but I'll take your word
for it ;-)
I'll try to explain:
When 'git-svn dcommit' decides which commits it should push back
subversion, it scans the output from 'git-log --first-parent HEAD'
looking for embedded 'git-svn-id' lines. These lines contain the url
of the upstream subversion repository + the subversion revision
number. So the problem with fast-forward merges of subversion branches
is that the output from 'git-log --first-parent HEAD' will show
commits from the wrong subversion branch (the fast-forwarded commits).
This could maybe be fixed in git-svn if it learned a different way of
discovering the upstream subversion branch, but then it would make
git-svn commit n revisions to subversion (again, the fast-forwarded
commits) instead of a single merge-commit. This would look (in
subversion) like a series of n cherry-picks from the merged branch.
Btw: maybe the --no-ff section in merge-options.txt could just link to
git-svn.txt, which in turn could have some lengthy explanation about
merge --no-ff/dcommit behaviour?
--
larsh
From: Johannes Schindelin <hidden> Date: 2016-06-15 22:43:35
Hi,
On Mon, 17 Sep 2007, Lars Hjemli wrote:
When 'git-svn dcommit' decides which commits it should push back
subversion, it scans the output from 'git-log --first-parent HEAD'
looking for embedded 'git-svn-id' lines. These lines contain the url
of the upstream subversion repository + the subversion revision
number.
So the problem with fast-forward merges of subversion branches is that
the output from 'git-log --first-parent HEAD' will show commits from the
wrong subversion branch (the fast-forwarded commits).
Ah, I think I know what you're trying to get at. But "git svn fetch &&
git rebase git-svn" might be a better approach than "git svn fetch && git
merge --no-ff git-svn", no?
Ciao,
Dscho
From: Chris Shoemaker <hidden> Date: 2016-06-15 22:43:35
On Mon, Sep 17, 2007 at 02:23:38PM +0100, Johannes Schindelin wrote:
Hi,
On Mon, 17 Sep 2007, Lars Hjemli wrote:
quoted
When 'git-svn dcommit' decides which commits it should push back
subversion, it scans the output from 'git-log --first-parent HEAD'
looking for embedded 'git-svn-id' lines. These lines contain the url
of the upstream subversion repository + the subversion revision
number.
quoted
So the problem with fast-forward merges of subversion branches is that
the output from 'git-log --first-parent HEAD' will show commits from the
wrong subversion branch (the fast-forwarded commits).
Ah, I think I know what you're trying to get at. But "git svn fetch &&
git rebase git-svn" might be a better approach [...]
BTW, this is spelled "git svn rebase" these days.
-chris
From: Lars Hjemli <hidden> Date: 2016-06-15 22:43:35
[Cc'd Eric since he's the expert on git-svn]
On 9/17/07, Johannes Schindelin [off-list ref] wrote:
Hi,
On Mon, 17 Sep 2007, Lars Hjemli wrote:
quoted
When 'git-svn dcommit' decides which commits it should push back
subversion, it scans the output from 'git-log --first-parent HEAD'
looking for embedded 'git-svn-id' lines. These lines contain the url
of the upstream subversion repository + the subversion revision
number.
quoted
So the problem with fast-forward merges of subversion branches is that
the output from 'git-log --first-parent HEAD' will show commits from the
wrong subversion branch (the fast-forwarded commits).
Ah, I think I know what you're trying to get at. But "git svn fetch &&
git rebase git-svn" might be a better approach than "git svn fetch && git
merge --no-ff git-svn", no?
If I'm understanding you right: no. After a rebase, the commits would
be ignored by git-svn when looking for the subversion upstream branch
(since the commit SHA1's would no longer match the ones stored in
git-svn's rev_db), but the subversion history would look like
'cherry-picked n commits from merged branch' after dcommit.
--
larsh
From: Johannes Schindelin <hidden> Date: 2016-06-15 22:43:35
Hi,
On Mon, 17 Sep 2007, Lars Hjemli wrote:
[Cc'd Eric since he's the expert on git-svn]
On 9/17/07, Johannes Schindelin [off-list ref] wrote:
quoted
Ah, I think I know what you're trying to get at. But "git svn fetch
&& git rebase git-svn" might be a better approach than "git svn fetch
&& git merge --no-ff git-svn", no?
If I'm understanding you right: no. After a rebase, the commits would be
ignored by git-svn when looking for the subversion upstream branch
(since the commit SHA1's would no longer match the ones stored in
git-svn's rev_db), but the subversion history would look like
'cherry-picked n commits from merged branch' after dcommit.
I feel that I am not really qualified here, since I am a strict git-svn
_user_, but AFAICT it worked here all the time, _especially_ with fast
forwards. The trick is that all commits that were added after the branch
point do _not_ contain any svn lines.
But then, I do not use svn branches here, and that might be the problem?
Ciao,
Dscho
From: Lars Hjemli <hidden> Date: 2016-06-15 22:43:35
On 9/17/07, Johannes Schindelin [off-list ref] wrote:
But then, I do not use svn branches here, and that might be the problem?
Probably. The case I'm trying to solve is:
-git-svn branch A is merged into git-svn branch B
-A is a fast-forward of B
This might look unrealistic, but it happened to me today when I wanted
to merge a feature-branch into a relase-branch. The release-branch had
previously been merged into the feature-branch (to get a few
bugfixes), but the release-branch had not changed since this merge. So
when merging the feature-branch into the release-branch it just
fast-forwarded, leaving me with an 'un-dcomittable' release-branch. I
obviously could have done the merge in subversion (haha!), but doing
it in git preserves the correct history.
Btw: I have redone the merge with --no-ff, and dcommit then worked
like a charm ;-)
--
larsh
From: Johannes Schindelin <hidden> Date: 2016-06-15 22:43:35
Hi,
On Mon, 17 Sep 2007, Lars Hjemli wrote:
On 9/17/07, Johannes Schindelin [off-list ref] wrote:
quoted
But then, I do not use svn branches here, and that might be the problem?
Probably. The case I'm trying to solve is:
-git-svn branch A is merged into git-svn branch B
-A is a fast-forward of B
This might look unrealistic, but it happened to me today when I wanted
to merge a feature-branch into a relase-branch. The release-branch had
previously been merged into the feature-branch (to get a few
bugfixes), but the release-branch had not changed since this merge. So
when merging the feature-branch into the release-branch it just
fast-forwarded, leaving me with an 'un-dcomittable' release-branch. I
obviously could have done the merge in subversion (haha!), but doing
it in git preserves the correct history.
Btw: I have redone the merge with --no-ff, and dcommit then worked
like a charm ;-)
Yep, I can see that now.
But maybe there is a better method to detect the latest svn id, by not
only looking up the svn ids, but making sure that they come from the
current branch?
(I'm happily unaware of git-svn's internals, so that might not be
feasible... But I think that it might be worth fixing that for the git-svn
idiot like me, since I would never guess that I have to specify --no-ff
when working on branches that come from git-svn...)
Ciao,
Dscho
From: Lars Hjemli <hidden> Date: 2016-06-15 22:43:35
On 9/17/07, Johannes Schindelin [off-list ref] wrote:
Hi,
On Mon, 17 Sep 2007, Lars Hjemli wrote:
quoted
On 9/17/07, Johannes Schindelin [off-list ref] wrote:
quoted
But then, I do not use svn branches here, and that might be the problem?
Probably. The case I'm trying to solve is:
-git-svn branch A is merged into git-svn branch B
-A is a fast-forward of B
This might look unrealistic, but it happened to me today when I wanted
to merge a feature-branch into a relase-branch. The release-branch had
previously been merged into the feature-branch (to get a few
bugfixes), but the release-branch had not changed since this merge. So
when merging the feature-branch into the release-branch it just
fast-forwarded, leaving me with an 'un-dcomittable' release-branch. I
obviously could have done the merge in subversion (haha!), but doing
it in git preserves the correct history.
Btw: I have redone the merge with --no-ff, and dcommit then worked
like a charm ;-)
Yep, I can see that now.
But maybe there is a better method to detect the latest svn id, by not
only looking up the svn ids, but making sure that they come from the
current branch?
Actually, I looked into this last week (my --upstream rants), and I
guess git-svn could use the --track information in .git/config (if
present) as a sanity check when resolving the upstream. But this would
still make the subversion history look like crap after a fast-forward
merge of the kind I was messing with today. It was logically a merge,
but if dcommit had worked 'correctly' it would have created ~150 new
revisions in the release-branch instead of the single merge commit.
(I'm happily unaware of git-svn's internals, so that might not be
feasible... But I think that it might be worth fixing that for the git-svn
idiot like me, since I would never guess that I have to specify --no-ff
when working on branches that come from git-svn...)
In the normal cases there is no need for --no-ff, only in degenerated
cases like the one I stumbled upon today ;-)
I'll resend the patch with a link from merge-options.txt to
git-svn.txt and try to describe (in git-svn.txt) when to use --no-ff.
--
larsh
From: Chris Shoemaker <hidden> Date: 2016-06-15 22:43:35
On Mon, Sep 17, 2007 at 04:12:56PM +0200, Lars Hjemli wrote:
On 9/17/07, Johannes Schindelin [off-list ref] wrote:
quoted
But then, I do not use svn branches here, and that might be the problem?
Probably. The case I'm trying to solve is:
-git-svn branch A is merged into git-svn branch B
-A is a fast-forward of B
Ah, now I see what you mean. But, IIUC, if you want to dcommit your
merge, you should treat it the way svn treats it, with git-merge
--squash. Then, dcommit won't be confused about the branch you're
committing to.
-chris
This might look unrealistic, but it happened to me today when I wanted
to merge a feature-branch into a relase-branch. The release-branch had
previously been merged into the feature-branch (to get a few
bugfixes), but the release-branch had not changed since this merge. So
when merging the feature-branch into the release-branch it just
fast-forwarded, leaving me with an 'un-dcomittable' release-branch. I
obviously could have done the merge in subversion (haha!), but doing
it in git preserves the correct history.
Btw: I have redone the merge with --no-ff, and dcommit then worked
like a charm ;-)
--
larsh
-
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
From: Lars Hjemli <hidden> Date: 2016-06-15 22:43:35
On 9/17/07, Chris Shoemaker [off-list ref] wrote:
On Mon, Sep 17, 2007 at 04:12:56PM +0200, Lars Hjemli wrote:
quoted
On 9/17/07, Johannes Schindelin [off-list ref] wrote:
quoted
But then, I do not use svn branches here, and that might be the problem?
Probably. The case I'm trying to solve is:
-git-svn branch A is merged into git-svn branch B
-A is a fast-forward of B
Ah, now I see what you mean. But, IIUC, if you want to dcommit your
merge, you should treat it the way svn treats it, with git-merge
--squash. Then, dcommit won't be confused about the branch you're
committing to.
Yeah, --squash is a viable option (I _almost_ used it ;-) but I wanted
to keep the merge-history on the git side (without modifying the
grafts-file).
--
larsh
From: Lars Hjemli <hidden> Date: 2016-06-15 22:43:35
This option forces fast-forward merges to create a "true" merge commit,
i.e. a commit with multiple parents.
Although a fast-forward merge would normally be the right thing to do with
git branches, it is suboptimal when operating on git-svn branches since it
makes 'git-svn dcommit' fail to recognize the correct upstream subversion
branch. But performing such a merge with --no-ff specified will both make
git-svn dcommit recognize the correct upstream and create the logically
correct history in subversion (the merge performed in git will be recorded
as a single revision in subversion, not as a series of revisions seemingly
cherry-picked from the merged branch).
Signed-off-by: Lars Hjemli <redacted>
---
When updating git-svn.txt, I noticed that we might want to update the
section "DESIGN PHILOSOPHY". Eric?
Documentation/git-svn.txt | 13 +++++++++++++
Documentation/merge-options.txt | 5 +++++
git-merge.sh | 13 +++++++++++--
t/t6028-merge-up-to-date.sh | 25 +++++++++++++++++++++++++
4 files changed, 54 insertions(+), 2 deletions(-)
@@ -475,6 +475,19 @@ use 'git-svn rebase' to update your work branch instead of 'git pull' or when committing into SVN, which can lead to merge commits reversing previous commits in SVN.+If you use 'git-svn dcommit' to commit your local work to the upstream+subversion branch, merge commits are usually handled correctly, i.e.+git-svn will only follow the first parent of each merge commit and create+a single subversion revision for each of them. An exception is when two+subversion branches has been merged locally and the merge ended up as a+fast-forward operation. This will make git-svn belive that there are no+local changes to dcommit. To work around this issue, one can redo the+merge using the --no-ff option:++ $ git reset --hard HEAD@{1} ## undo the fast-forward merge+ $ git merge --no-ff <branch>++ DESIGN PHILOSOPHY ----------------- Merge tracking in Subversion is lacking and doing branched development
@@ -25,3 +25,8 @@ If there is no `-s` option, a built-in list of strategies is used instead (`git-merge-recursive` when merging a single head, `git-merge-octopus` otherwise).++--no-ff::+ Force the creation of a merge commit even when the merge would+ have resolved as a fast-forward operation. See gitlink:git-svn[1]+ for a use-case for this option.
@@ -444,7 +448,12 @@ done# auto resolved the merge cleanly.iftest''!="$result_tree"then-parents=$(gitshow-branch--independent"$head""$@"|sed-e's/^/-p /')+iftest$no_ff='t'+then+parents=$(gitrev-parse"$head""$@"|sed-e's/^/-p /')+else+parents=$(gitshow-branch--independent"$head""$@"|sed-e's/^/-p /')+firesult_commit=$(printf'%s\n'"$merge_msg"|gitcommit-tree$result_tree$parents)||exitfinish"$result_commit""Merge made by $wt_strategy."dropsave
From: Eric Wong <hidden> Date: 2016-06-15 22:43:35
Lars Hjemli [off-list ref] wrote:
This option forces fast-forward merges to create a "true" merge commit,
i.e. a commit with multiple parents.
Although a fast-forward merge would normally be the right thing to do with
git branches, it is suboptimal when operating on git-svn branches since it
makes 'git-svn dcommit' fail to recognize the correct upstream subversion
branch. But performing such a merge with --no-ff specified will both make
git-svn dcommit recognize the correct upstream and create the logically
correct history in subversion (the merge performed in git will be recorded
as a single revision in subversion, not as a series of revisions seemingly
cherry-picked from the merged branch).
Signed-off-by: Lars Hjemli <redacted>
Would automatically enabling --no-ff when it detects merging of two (or
more) SVN branches be a good thing? We can add scripting support to
git-svn for detecting if any given commit is really from SVN or not.
Then we could do something like this in git-merge
---------------------------- 8< --------------------------------
if git-svn test-svn-commits "$@"
then
no_ff=t
no_fast_forward_strategies=$all_strategies
fi
---------------------------- 8< --------------------------------
It'd probably prevent a lot of users from shooting themselves in the
foot if they forget to read or learn about the --no-ff option.
---
When updating git-svn.txt, I noticed that we might want to update the
section "DESIGN PHILOSOPHY". Eric?
Yeah. That's very much out of date. I'll update it in a bit.
--
Eric Wong
From: Eric Wong <hidden> Date: 2016-06-15 22:43:35
Lars Hjemli [off-list ref] wrote:
On 9/18/07, Eric Wong [off-list ref] wrote:
quoted
Would automatically enabling --no-ff when it detects merging of two (or
more) SVN branches be a good thing?
I'd say 'git-svn merge' as a wrapper for 'git merge --no-ff' would be cleaner.
That still involves having to get the user to use something new to avoid
shooting themselves in the foot. Perhaps putting a
"test -d $GIT_DIR/svn" condition in front of the git-svn call I proposed
in git-merge would be alright.
If anybody else is thinking about 'git-svn rebase', this is completely
different. Using git-rebase alone doesn't allow git-svn users to shoot
themselves in the foot like git-merge does. 'git-svn rebase' only
serves to minimize typing and brain power needed to operate git-svn.
--
Eric Wong
From: Peter Baumann <hidden> Date: 2016-06-15 22:43:35
On Mon, Sep 17, 2007 at 06:23:04PM +0200, Lars Hjemli wrote:
quoted hunk
This option forces fast-forward merges to create a "true" merge commit,
i.e. a commit with multiple parents.
Although a fast-forward merge would normally be the right thing to do with
git branches, it is suboptimal when operating on git-svn branches since it
makes 'git-svn dcommit' fail to recognize the correct upstream subversion
branch. But performing such a merge with --no-ff specified will both make
git-svn dcommit recognize the correct upstream and create the logically
correct history in subversion (the merge performed in git will be recorded
as a single revision in subversion, not as a series of revisions seemingly
cherry-picked from the merged branch).
Signed-off-by: Lars Hjemli <redacted>
---
When updating git-svn.txt, I noticed that we might want to update the
section "DESIGN PHILOSOPHY". Eric?
Documentation/git-svn.txt | 13 +++++++++++++
Documentation/merge-options.txt | 5 +++++
git-merge.sh | 13 +++++++++++--
t/t6028-merge-up-to-date.sh | 25 +++++++++++++++++++++++++
4 files changed, 54 insertions(+), 2 deletions(-)
@@ -475,6 +475,19 @@ use 'git-svn rebase' to update your work branch instead of 'git pull' or when committing into SVN, which can lead to merge commits reversing previous commits in SVN.+If you use 'git-svn dcommit' to commit your local work to the upstream+subversion branch, merge commits are usually handled correctly, i.e.+git-svn will only follow the first parent of each merge commit and create+a single subversion revision for each of them. An exception is when two+subversion branches has been merged locally and the merge ended up as a+fast-forward operation. This will make git-svn belive that there are no+local changes to dcommit. To work around this issue, one can redo the+merge using the --no-ff option:++ $ git reset --hard HEAD@{1} ## undo the fast-forward merge+ $ git merge --no-ff <branch>++ DESIGN PHILOSOPHY ----------------- Merge tracking in Subversion is lacking and doing branched development
@@ -25,3 +25,8 @@ If there is no `-s` option, a built-in list of strategies is used instead (`git-merge-recursive` when merging a single head, `git-merge-octopus` otherwise).++--no-ff::+ Force the creation of a merge commit even when the merge would+ have resolved as a fast-forward operation. See gitlink:git-svn[1]+ for a use-case for this option.
@@ -444,7 +448,12 @@ done# auto resolved the merge cleanly.iftest''!="$result_tree"then-parents=$(gitshow-branch--independent"$head""$@"|sed-e's/^/-p /')+iftest$no_ff='t'
This should be quoted, e.g.
+ if test "$no_ff" = 't'
Otherwise I get an error like the following:
xp:/tmp/va (a)$ git merge b
Renamed msg.cc->common/msg.cc
Auto-merged common/msg.cc
Renamed msg.h->common/msg.h
Auto-merged common/msg.h
Renamed sampler/ConcurrentQueue.h->common/ConcurrentQueue.h
Auto-merged common/ConcurrentQueue.h
Renamed sampler/TimeoutSemaphore.h->common/TimeoutSemaphore.h
Auto-merged common/TimeoutSemaphore.h
/home/peter/usr/bin/git-merge: line 451: test: =: unary operator expected
Merge made by recursive.
+ then
+ parents=$(git rev-parse "$head" "$@" | sed -e 's/^/-p /')
+ else
+ parents=$(git show-branch --independent "$head" "$@" | sed -e 's/^/-p /')
+ fi
result_commit=$(printf '%s\n' "$merge_msg" | git commit-tree $result_tree $parents) || exit
finish "$result_commit" "Merge made by $wt_strategy."
dropsave