git-svn: make git-svn commit-diff able to work without explicit arguments
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 ?
Quoted 26 lines · Steve Frécinaux
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 HEADWhich 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.
Quoted 4 lines
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-svn2. 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 :)
Signature · 3 lines
·O· Pierre Habouzit ··O [email protected] OOO http://www.madism.org
Quoted 10 lines · Steve Fr?cinaux
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 :
Quoted 8 lines
git-svn commit-diff --edit -r$REV remotes/git-svn HEADWhich 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.
Quoted 9 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'.
Signature · 1 line
Eric Wong
Quoted 5 lines · Steve Frécinaux
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.
Quoted 20 lines · Junio C Hamano
Quoted 5 lines · Steve Frécinaux
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.
Quoted 6 lines
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.
Signature · 3 lines
·O· Pierre Habouzit ··O [email protected] OOO http://www.madism.org
Quoted 11 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
Quoted 13 lines · Brian Gernhardt
Quoted 4 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:Quoted 8 lines
{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.
Quoted 8 lines
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.
Signature · 3 lines
Jakub Narebski Warsaw, Poland ShadeHawk on #git
Quoted 18 lines · Jakub Narebski
Quoted 16 lines · Brian Gernhardt
Quoted 4 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:Quoted 8 lines
{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:
Quoted 8 lines
Quoted 5 lines
$ git cherry-pick A $ git cherry-pick C $ git reset HEAD~2 $ git add <files> $ git commitOr 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 ...
Signature · 3 lines
·O· Pierre Habouzit ··O [email protected] OOO http://www.madism.org
Quoted 3 lines · Pierre Habouzit
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.
Quoted 10 lines · Pierre Habouzit
... 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.