threads / rfc / 6196

[RFC] git-svn: make git-svn commit-diff able to work without explicit arguments

Subject: [RFC] git-svn: make git-svn commit-diff able to work without explicit arguments

## tl;dr

10 messages between Jan 2, 2007 and Jan 2, 2007.

replies: 9people: 6as markdown or json

Steve Frécinaux· Jan 2, 2007, 18:23 UTC · lore
Hello,

When using git-svn to access a SVN repo, the commit policy may vary. While git makes you commit small patches often, svn users tend to prefer bigger patches that implement a functionnality at once.

So at the end you have a SVN commit which corresponds to several git ones.
What you can do in this case is :
   git-svn commit-diff --edit -r$REV remotes/git-svn HEAD

Which effect is that it commits (at once) all the commits between the latest svn fetch and HEAD.

What I'm proposing here is this:
  - use the latest fetched rev the default for the -r argument.
  - use remotes/git-svn and HEAD the defaults for the treeish objects.

A smarter way to take these defaults would be to take the last revision in the current branch (which can be something else than git-svn if it wasn't rebased/merged recently) and the relevant commit in the current branch.

Additionnaly, --edit could be enabled by default if -m is not set and it is used interactively, eventually using an option in repo-config.

Any comment ?
Pierre Habouzit· Jan 2, 2007, 18:40 UTC · re: Steve Frécinaux · lore

[RFC] Re: git-svn: make git-svn commit-diff able to work without explicit arguments

On Tue, Jan 02, 2007 at 07:23:26PM +0100, Steve Frécinaux wrote:
Show 30 quoted lines
> Hello,
> 
> When using git-svn to access a SVN repo, the commit policy may vary. 
> While git makes you commit small patches often, svn users tend to prefer 
> bigger patches that implement a functionnality at once.
> 
> So at the end you have a SVN commit which corresponds to several git 
> ones.
> 
> What you can do in this case is :
> 
>   git-svn commit-diff --edit -r$REV remotes/git-svn HEAD
> 
> Which effect is that it commits (at once) all the commits between the 
> latest svn fetch and HEAD.
> 
> What I'm proposing here is this:
> 
>  - use the latest fetched rev the default for the -r argument.
>  - use remotes/git-svn and HEAD the defaults for the treeish objects.
> 
> A smarter way to take these defaults would be to take the last revision 
> in the current branch (which can be something else than git-svn if it 
> wasn't rebased/merged recently) and the relevant commit in the current 
> branch.
> 
> Additionnaly, --edit could be enabled by default if -m is not set and it 
> is used interactively, eventually using an option in repo-config.
> 
> Any comment ?
  of course a git svn subcommand that in fact allow you to cherry pick
patches from `git rev-list remotes/git-svn` would be *really* good, but
here is what I do:
  1. be up2date:
    $ git svn fetch
    $ git rebase remotes/git-svn
  2. create a local branch to cherry pick the hunk you want to combine:
    $ git branch -f svn-tmp remotes/git-svn
    # cherry pick the commits you want using any method you like, eg:
    $ git cherry-pick <....>
     or
    $ git am [some previously built mailbox of changes]
    I happen to prefer the later since I do git format-patch
    remotes/git-svn from my master branch, and use my MUA as a
    poor-man's interactive way to select patches I want. Though
    sometimes you miss some dependant patches, and I suppose git
    cherry-pick would be better at that game, YMMV.
  3. git svn commit HEAD (not dcommit) to force merging of all your
     local patches in one svn changeset.
     note that you may need a step (1) update if anything changed since,
     if you don't want to see git-svn undo the commits other user may
     have done since your last (1) update, commit your change, and
     commit the previously undone commits back. I did that once when I
     was a beginner with git-svn, and it generated a huge pile of
     globally indempotend commits, and flooded the commit mail list,
     that was kind of funny ;)
  4. go back to your branch as usual, and resync to the new svn state:
     git checkout master
     git svn fetch
     git rebase remotes/git-svn # should merge things happily
     you can then go back to (2) and iterate until your
     `git rev-list remotes/git-svn` is empty.
  This is highly unpretty, and relies in the fact that nobody commited
into the svn between your set 2 and 3. I suppose you can achieve the
same by creating combined changeset from git, instead of a cherry
picking, in some kind of "combining" branch, and then just use
`git svn dcommit` from there, but I've found no convenient (I mean no
way *I* find convenient) way to do that. Maybe someone here has a better
idea :)
-- 
·O·  Pierre Habouzit
··O                                                madcoder@debian.org
OOO                                                http://www.madism.org
Eric Wong· Jan 2, 2007, 19:18 UTC · re: Steve Frécinaux · lore

Re: [RFC] git-svn: make git-svn commit-diff able to work without explicit arguments

Steve Fr?cinaux <nudrema@gmail.com> wrote:
Show 18 quoted lines
> Hello,
> 
> When using git-svn to access a SVN repo, the commit policy may vary. 
> While git makes you commit small patches often, svn users tend to prefer 
> bigger patches that implement a functionnality at once.
> 
> So at the end you have a SVN commit which corresponds to several git ones.
> 
> What you can do in this case is :
> 
>   git-svn commit-diff --edit -r$REV remotes/git-svn HEAD
> 
> Which effect is that it commits (at once) all the commits between the 
> latest svn fetch and HEAD.
> 
> What I'm proposing here is this:
> 
>  - use the latest fetched rev the default for the -r argument.
Yes, this is very important.
Show 9 quoted lines
>  - use remotes/git-svn and HEAD the defaults for the treeish objects.
> 
> A smarter way to take these defaults would be to take the last revision 
> in the current branch (which can be something else than git-svn if it 
> wasn't rebased/merged recently) and the relevant commit in the current 
> branch.
> 
> Additionnaly, --edit could be enabled by default if -m is not set and it 
> is used interactively, eventually using an option in repo-config.

This sounds useful. This is basically what 'set-tree' (the command formerly known as 'commit') was meant to do originally. Unlike set-tree (or perhaps with modifying set-tree), this should rebase or reset afterwards to linearize history like 'dcommit'.

-- 
Eric Wong
Junio C Hamano· Jan 2, 2007, 20:30 UTC · re: Steve Frécinaux · lore

Re: [RFC] git-svn: make git-svn commit-diff able to work without explicit arguments

Steve Frécinaux <nudrema@gmail.com> writes:
Show 5 quoted lines
> When using git-svn to access a SVN repo, the commit policy may
> vary. While git makes you commit small patches often, svn users tend
> to prefer bigger patches that implement a functionnality at once.
>
> So at the end you have a SVN commit which corresponds to several git ones.

I personally think this is solving a wrong problem. Commit granularity is a property of the project, the way in which people involved in the project prefer working. It is not about "svn users" vs "git users", and it shouldn't be, especially if the end result is still a single project.

Is git "making you commit small patches often"? I honestly hope we are not forcing you to do so, although we took pains to make it easier because it tends to be easier to look at the history later when commit boundaries match the logical steps of evolution.

So my suggestion would be to educate people who tend to make too large commits better separate their commits, and at the same time coallesce the commits you create on the git side into a presentable size, if you acquired a bad habit of making too small commits, so that everybody follows the same commit granularity guideline set by the project.

Pierre Habouzit· Jan 2, 2007, 21:13 UTC · re: Junio C Hamano · lore

[RFC] Re: git-svn: make git-svn commit-diff able to work without explicit arguments

On Tue, Jan 02, 2007 at 12:30:16PM -0800, Junio C Hamano wrote:
Show 26 quoted lines
> Steve Frécinaux <nudrema@gmail.com> writes:
> 
> > When using git-svn to access a SVN repo, the commit policy may
> > vary. While git makes you commit small patches often, svn users tend
> > to prefer bigger patches that implement a functionnality at once.
> >
> > So at the end you have a SVN commit which corresponds to several git ones.
> 
> I personally think this is solving a wrong problem.  Commit
> granularity is a property of the project, the way in which
> people involved in the project prefer working.  It is not about
> "svn users" vs "git users", and it shouldn't be, especially if
> the end result is still a single project.
> 
> Is git "making you commit small patches often"?  I honestly hope
> we are not forcing you to do so, although we took pains to make
> it easier because it tends to be easier to look at the history
> later when commit boundaries match the logical steps of
> evolution.
> 
> So my suggestion would be to educate people who tend to make too
> large commits better separate their commits, and at the same
> time coallesce the commits you create on the git side into a
> presentable size, if you acquired a bad habit of making too
> small commits, so that everybody follows the same commit
> granularity guideline set by the project.
  Though an operation that I'd often like to do is to merge two (or
more) patches as one, and reedit its entry, preferably as a merge of the
two (or more) old logs.
  The reason is simple, I often use git commit as :wq in my editor, and
sometimes think that in a A--B--C--D and in fact, I'd prefer to have:
  {A,C}--B--D. how is it possible to do that in a not too cumbersome
way? because that would make sens to work in some scratch branch, and
then reorganize patches in a saner better way in the master branch.
  But I fail to see how to achieve that without using cumbersome
export-to-patch then git apply patch and edit logs which is painful and
not really using git.
-- 
·O·  Pierre Habouzit
··O                                                madcoder@debian.org
OOO                                                http://www.madism.org
Brian Gernhardt· Jan 2, 2007, 21:26 UTC · re: Pierre Habouzit · lore

Re: [RFC] Re: git-svn: make git-svn commit-diff able to work without explicit arguments

Show 12 quoted lines
>   The reason is simple, I often use git commit as :wq in my editor,  
> and
> sometimes think that in a A--B--C--D and in fact, I'd prefer to have:
>
>   {A,C}--B--D. how is it possible to do that in a not too cumbersome
> way? because that would make sens to work in some scratch branch, and
> then reorganize patches in a saner better way in the master branch.
>
>   But I fail to see how to achieve that without using cumbersome
> export-to-patch then git apply patch and edit logs which is painful  
> and
> not really using git.

The command you seem to be looking for is git-cherry-pick. To combine the two commits, I'd do something like:

$ git cherry-pick A $ git cherry-pick C $ git reset HEAD~2 $ git add <files> $ git commit

And then you could rebase the work branch on top of the new master, which should catch that A and C were already committed with minimal effort. Of course there may be a cleaner way to do it, but this is what I do.

~~ Brian Gernhardt
Jakub Narebski· Jan 2, 2007, 21:58 UTC · re: Brian Gernhardt · lore

Re: [RFC] Re: git-svn: make git-svn commit-diff able to work without explicit arguments

Brian Gernhardt wrote:
Show 21 quoted lines
>>   The reason is simple, I often use git commit as :wq in my editor,  
>> and
>> sometimes think that in a A--B--C--D and in fact, I'd prefer to have:
>>
>>   {A,C}--B--D. how is it possible to do that in a not too cumbersome
>> way? because that would make sens to work in some scratch branch, and
>> then reorganize patches in a saner better way in the master branch.
>>
>>   But I fail to see how to achieve that without using cumbersome
>> export-to-patch then git apply patch and edit logs which is painful  
>> and
>> not really using git.
> 
> The command you seem to be looking for is git-cherry-pick.  To  
> combine the two commits, I'd do something like:
> 
> $ git cherry-pick A
> $ git cherry-pick C
> $ git reset HEAD~2
> $ git add <files>
> $ git commit

Or better learn about --no-commit option of git-cherry-pick. Or if you don't mind additional tools I think you can do this using StGIT.

-- 
Jakub Narebski
Warsaw, Poland
ShadeHawk on #git
Pierre Habouzit· Jan 2, 2007, 22:27 UTC · re: Jakub Narebski · lore

[RFC] Re: git-svn: make git-svn commit-diff able to work without explicit arguments

On Tue, Jan 02, 2007 at 10:58:14PM +0100, Jakub Narebski wrote:
Show 26 quoted lines
> Brian Gernhardt wrote:
> 
> >>   The reason is simple, I often use git commit as :wq in my editor,  
> >> and
> >> sometimes think that in a A--B--C--D and in fact, I'd prefer to have:
> >>
> >>   {A,C}--B--D. how is it possible to do that in a not too cumbersome
> >> way? because that would make sens to work in some scratch branch, and
> >> then reorganize patches in a saner better way in the master branch.
> >>
> >>   But I fail to see how to achieve that without using cumbersome
> >> export-to-patch then git apply patch and edit logs which is painful  
> >> and
> >> not really using git.
> > 
> > The command you seem to be looking for is git-cherry-pick.  To  
> > combine the two commits, I'd do something like:
> > 
> > $ git cherry-pick A
> > $ git cherry-pick C
> > $ git reset HEAD~2
> > $ git add <files>
> > $ git commit
> 
> Or better learn about --no-commit option of git-cherry-pick. Or if you
> don't mind additional tools I think you can do this using StGIT.
  oh those solutions look awsome and easily scriptable, which is
exactly what I need, and it feels simpler to use for my small brain than
the solution Junio proposed. thanks a lot !
  I wonder why I never got to that alone ...
-- 
·O·  Pierre Habouzit
··O                                                madcoder@debian.org
OOO                                                http://www.madism.org
Junio C Hamano· Jan 2, 2007, 22:01 UTC · re: Pierre Habouzit · lore

Re: [RFC] Re: git-svn: make git-svn commit-diff able to work without explicit arguments

Pierre Habouzit <madcoder@debian.org> writes:
Show 10 quoted lines
> ... and
> sometimes think that in a A--B--C--D and in fact, I'd prefer to have:
>
>   {A,C}--B--D. how is it possible to do that in a not too cumbersome
> way? because that would make sens to work in some scratch branch, and
> then reorganize patches in a saner better way in the master branch.
>
>   But I fail to see how to achieve that without using cumbersome
> export-to-patch then git apply patch and edit logs which is painful and
> not really using git.

First of all, "format-patch and then edit" is a perfectly sane way to use git. Any workflow that takes advantage of cheap branch creatin and cheap resetting of the tip of a branch _is_ "really using git". It depends on the size of the series you are redoing, but I do that all the time.

Also cherry-pick, rebase, squash merge are your friends.

If you are on $original branch (which may be your 'master') with commits A--B--C--D:

	git checkout -b temp HEAD~3 ;# that's A
        git cherry-pick $original~1 ;# that's C
	git checkout $original
        git rebase temp
would make the $original A--C'-B'-D'.  Then:
	git checkout temp ; git reset --hard $original~4 ;# parent of A
	git merge -s squash $original~2 ;# squash A and C'

would prepare you to make a squashed commit out of the two to the temp branch. Then:

	git checkout $original
        git rebase --onto temp HEAD~2 ;# that's C'
	git branch -d temp
would give you (A+C)--B'-D' on $original branch.

StGIT would make life even easier for you. It is designed to make things like the above simpler.

Steve Frécinaux· Jan 2, 2007, 23:09 UTC · re: Pierre Habouzit · lore

Re: [RFC] Re: git-svn: make git-svn commit-diff able to work without explicit arguments

Pierre Habouzit wrote:
>   Though an operation that I'd often like to do is to merge two (or
> more) patches as one, and reedit its entry, preferably as a merge of the
> two (or more) old logs.

Actually that's more or less what I wanted to achieve, just that it was less general.

Using the solutions that have been proposed in this thread (using git-cherry-pick -n and a work branch) looks satisfying for what I want to do. Then it's just a matter of cherry-picking the last "work" patches, commiting them as a whole in master and then using git-svn dcommit the regular way.

← back to recent threads