git-submodule: add support for --rebase.
'git submodule update --rebase' rebases onto the current branch rather than detaching the HEAD.
---
I use git-submodule to keep track of repositories that I only infrequently commit to. I keep them to have a set that is known to work.
git submodule update is annoying, as it (in my case needlessly) detaches the HEAD, making the workflow more complicated when I do have to commit (checkout master, rebase onto master, then commit).
This patch adds a "--rebase" flag to git submodule update that calls git-rebase instead of git-checkout.
Any comments? Is there a better solution for this problem?
Cheers,
Peter
Documentation/git-submodule.txt | 11 +++++++++-- git-submodule.sh | 21 +++++++++++++++++---- 2 files changed, 26 insertions(+), 6 deletions(-)
Documentation/git-submodule.txt +9 -2
@@ -12,7 +12,7 @@ SYNOPSIS 'git submodule' [--quiet] add [-b branch] [--] <repository> <path> 'git submodule' [--quiet] status [--cached] [--] [<path>...] 'git submodule' [--quiet] init [--] [<path>...] -'git submodule' [--quiet] update [--init] [-N|--no-fetch] [--] [<path>...] +'git submodule' [--quiet] update [--init] [-N|--no-fetch] [--rebase] [--] [<path>...] 'git submodule' [--quiet] summary [--summary-limit <n>] [commit] [--] [<path>...] 'git submodule' [--quiet] foreach <command> 'git submodule' [--quiet] sync [--] [<path>...]
@@ -113,7 +113,8 @@ init:: update:: Update the registered submodules, i.e. clone missing submodules and checkout the commit specified in the index of the containing repository. - This will make the submodules HEAD be detached. + This will make the submodules HEAD be detached unless '--rebase' is + specified. + If the submodule is not yet initialized, and you just want to use the setting as stored in .gitmodules, you can automatically initialize the
@@ -177,6 +178,12 @@ OPTIONS This option is only valid for the update command. Don't fetch new objects from the remote site. +--rebase:: + This option is only valid for the update command. + Forward-port local commits to the index of the containing repository. + If a a merge failure prevents this process, you will have to resolve + these failures with linkgit:git-rebase[1]. + <path>...:: Paths to submodule(s). When specified this will restrict the command to only operate on the submodules found at the specified paths.
git-submodule.sh +17 -4
@@ -17,6 +17,7 @@ branch= quiet= cached= nofetch= +rebase= # # print stuff on stdout unless -q was specified
@@ -314,6 +315,10 @@ cmd_update() shift nofetch=1 ;; + -r|--rebase) + shift + rebase=1 + ;; --) shift break
@@ -367,11 +372,19 @@ cmd_update() die "Unable to fetch in submodule path '$path'" fi - (unset GIT_DIR; cd "$path" && - git-checkout $force -q "$sha1") || - die "Unable to checkout '$sha1' in submodule path '$path'" + if test -z "$rebase" + then + (unset GIT_DIR; cd "$path" && + git-checkout $force -q "$sha1") || + die "Unable to checkout '$sha1' in submodule path '$path'" + say "Submodule path '$path': checked out '$sha1'" + else + (unset GIT_DIR; cd "$path" && + git-rebase "$sha1") || + die "Unable to rebase onto '$sha1' in submodule path '$path'" + say "Submodule path '$path': rebased onto '$sha1'" + fi - say "Submodule path '$path': checked out '$sha1'" fi done }
Signature · 1 line
1.6.2.2.447.ge953ab
Hi,
Disclaimer: if you are offended by constructive criticism, or likely to answer with insults to the comments I offer, please stop reading this mail now (and please do not answer my mail, either). :-)
Still with me? Good. Nice to meet you.
Just for the record: responding to a patch is my strongest way of saying that I appreciate your work.
Quoted 2 lines · Peter Hutterer
'git submodule update --rebase' rebases onto the current branch rather than detaching the HEAD.
I know what you want to do, but this text is wrong: it should rather read something like this:
'git submodule update --rebase' rebases your local branch on top of what would have been checked out to a detached HEAD otherwise.
Maybe some of these native English speakers on this list can come up with something even better ;-)
Quoted 9 lines
I use git-submodule to keep track of repositories that I only infrequently commit to. I keep them to have a set that is known to work.
git submodule update is annoying, as it (in my case needlessly) detaches the HEAD, making the workflow more complicated when I do have to commit (checkout master, rebase onto master, then commit).
This patch adds a "--rebase" flag to git submodule update that calls git-rebase instead of git-checkout.
Maybe a non-first person version of this comment could go into the commit message, too? I found this highly informative.
Documentation/git-submodule.txt OPTIONS · line 182
Quoted 10 lines
Documentation/git-submodule.txt +2
-0@@ -177,6 +178,12 @@ OPTIONS This option is only valid for the update command. Don't fetch new objects from the remote site. +--rebase:: + This option is only valid for the update command.
This is unnecessary, it was mentioned in the synopsis.
Documentation/git-submodule.txt OPTIONS · line 183
Quoted 1 line
Documentation/git-submodule.txt +1
-0+ Forward-port local commits to the index of the containing repository.
This is a bit misleading/unclear. I'd rather have it read like this:
Instead of detaching the HEAD to the revision committed in the superproject, rebase the current branch onto that revision.
git-submodule.sh
Quoted 10 lines
Documentation/git-submodule.txt +3
-0+ If a a merge failure prevents this process, you will have to resolve + these failures with linkgit:git-rebase[1]. + <path>...:: Paths to submodule(s). When specified this will restrict the command to only operate on the submodules found at the specified paths.git-submodule.sh +0
-0
You might want to error out when --rebase was passed with another command than "update".
Quoted 9 lines
git-submodule.sh +2
-3@@ -367,11 +372,19 @@ cmd_update() die "Unable to fetch in submodule path '$path'" fi - (unset GIT_DIR; cd "$path" && - git-checkout $force -q "$sha1") || - die "Unable to checkout '$sha1' in submodule path '$path'" + if test -z "$rebase" + then
git-submodule.sh cmd_update() · line 386
Quoted 10 lines
git-submodule.sh +10
-0+ (unset GIT_DIR; cd "$path" && + git-checkout $force -q "$sha1") || + die "Unable to checkout '$sha1' in submodule path '$path'" + say "Submodule path '$path': checked out '$sha1'" + else + (unset GIT_DIR; cd "$path" && + git-rebase "$sha1") || + die "Unable to rebase onto '$sha1' in submodule path '$path'" + say "Submodule path '$path': rebased onto '$sha1'" + fi
I'd actually put the "(unset GIT_DIR; cd "$path" &&" in front of the "if" due to the DRY principle (Don't Repeat Yourself).
In the same spirit, I'd set a variable "action" to "checkout" or "rebase onto" and munge the error/info message to use $action.
Maybe you want to add a single primitive test case to make sure this feature will not get broken in the future?
Other than that: nice! very nice!
Ciao,
Dscho
P.S.: the next patch is obvious, too: add support to specify desire to rebase the submodule in .gitmodules and .git/config.
Quoted 8 lines · Johannes Schindelin
Disclaimer: if you are offended by constructive criticism, or likely to answer with insults to the comments I offer, please stop reading this mail now (and please do not answer my mail, either). :-)
Still with me? Good. Nice to meet you.
Just for the record: responding to a patch is my strongest way of saying that I appreciate your work.
Thanks for the review, the updated patch is below.
Changes:
- Commit message extended with a description of why this patch is handy.
- Less duplication in the if --rebase/else condition.
- Test case included. The test updates with and without rebase and compares the sha of HEAD to the sha of the master branch.
I do have a few other comments though:
Quoted 6 lines
Quoted 2 lines
'git submodule update --rebase' rebases onto the current branch rather than detaching the HEAD.
I know what you want to do, but this text is wrong: it should rather read something like this:
Quoted 6 lines
'git submodule update --rebase' rebases your local branch on top of what would have been checked out to a detached HEAD otherwise.
Maybe some of these native English speakers on this list can come up with something even better ;-)
amended to your version, see below.
Quoted 7 lines
Quoted 7 lines
I use git-submodule to keep track of repositories that I only infrequently commit to. I keep them to have a set that is known to work.
git submodule update is annoying, as it (in my case needlessly) detaches the HEAD, making the workflow more complicated when I do have to commit (checkout master, rebase onto master, then commit).
Quoted 5 lines
Quoted 2 lines
This patch adds a "--rebase" flag to git submodule update that calls git-rebase instead of git-checkout.
Maybe a non-first person version of this comment could go into the commit message, too? I found this highly informative.
amended, see below
Quoted 8 lines
Quoted 8 lines
Documentation/git-submodule.txt +0
-0@@ -177,6 +178,12 @@ OPTIONS This option is only valid for the update command. Don't fetch new objects from the remote site.
Quoted 4 lines
Documentation/git-submodule.txt OPTIONS · line 182
Quoted 2 lines
Documentation/git-submodule.txt +2
-0+--rebase:: + This option is only valid for the update command.This is unnecessary, it was mentioned in the synopsis.
Correct, but in the same file the options --cached, --no-fetch, and --summary-limit do state that they are only valid for the update/status/summary commands, respectively. For consistency, we should either add this sentence to --rebase, or remove them from the others. I personally prefer having it there, just to make it more obvious.
Quoted 6 lines
Documentation/git-submodule.txt OPTIONS · line 183
Quoted 1 line
Documentation/git-submodule.txt +1
-0+ Forward-port local commits to the index of the containing repository.This is a bit misleading/unclear. I'd rather have it read like this:
Instead of detaching the HEAD to the revision committed in the superproject, rebase the current branch onto that revision.
Hehe. I had something like this before and then decided to copy/paste the line from the git-rebase man page :)
Changed to: "Rebase the current branch onto the index of the containing repository instead of detaching the HEAD." (I vaguely remember the rule that sentences are easier to understand if you have "blah instead of foo" rather than "instead of foo, blah")
The phrase "index of the containing repository" is commonly used in this man page, so I think it's best to stick with it.
That better now?
Quoted 5 lines
Quoted 5 lines
Documentation/git-submodule.txt +3
-0+ If a a merge failure prevents this process, you will have to resolve + these failures with linkgit:git-rebase[1]. + <path>...:: Paths to submodule(s). When specified this will restrict the command
Quoted 8 lines
git-submodule.sh
Quoted 5 lines
Documentation/git-submodule.txt +0
-0to only operate on the submodules found at the specified paths.git-submodule.sh +0
-0You might want to error out when --rebase was passed with another command than "update".
cmd_init(), cmd_summary(), etc. have catch-all rules for unknown options to display the usage, so this is covered. (e.g. line 439, git-submodule.sh)
Quoted 23 lines
Quoted 9 lines
git-submodule.sh +2
-3@@ -367,11 +372,19 @@ cmd_update() die "Unable to fetch in submodule path '$path'" fi - (unset GIT_DIR; cd "$path" && - git-checkout $force -q "$sha1") || - die "Unable to checkout '$sha1' in submodule path '$path'" + if test -z "$rebase" + thengit-submodule.sh cmd_update() · line 386
Quoted 10 lines
git-submodule.sh +10
-0+ (unset GIT_DIR; cd "$path" && + git-checkout $force -q "$sha1") || + die "Unable to checkout '$sha1' in submodule path '$path'" + say "Submodule path '$path': checked out '$sha1'" + else + (unset GIT_DIR; cd "$path" && + git-rebase "$sha1") || + die "Unable to rebase onto '$sha1' in submodule path '$path'" + say "Submodule path '$path': rebased onto '$sha1'" + fiI'd actually put the "(unset
GIT_DIR; cd "$path" &&" in front of the "if" due to the DRY principle (Don't Repeat Yourself).
Quoted 2 lines
In the same spirit, I'd set a variable "action" to "checkout" or "rebase onto" and munge the error/info message to use $action.
amended, see patch below
Quoted 10 lines
Maybe you want to add a single primitive test case to make sure this feature will not get broken in the future?
Other than that: nice! very nice!
Ciao,
Dscho
P.S.: the next patch is obvious, too: add support to specify desire to rebase the submodule in .gitmodules and .git/config.
Cheers,
Peter
Quoted 1 line
From
b5ed1a17aa9b6042f68a546ceb3990b65d0862e0Mon Sep 17 00:00:00 2001
From: Peter Hutterer <[email protected]>
Date: Fri, 27 Mar 2009 13:42:42 +1000
Subject: [PATCH] git-submodule: add support for --rebase.
'git submodule update --rebase' rebases your local branch on top of what would have been checked out to a detached HEAD otherwise.
In some cases, detaching the HEAD when updating a submodule complicates the workflow to commit to this submodule (checkout master, rebase, then commit). For submodules that require frequent updates but infrequent (if any) commits, a rebase can be executed directly by the git-submodule command, ensuring that the submodules stay on their respective branches.
--- Documentation/git-submodule.txt | 12 +++++- git-submodule.sh | 22 +++++++++-- t/t7404-submodule-update.sh | 79 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 107 insertions(+), 6 deletions(-) create mode 100755 t/t7404-submodule-update.sh
Documentation/git-submodule.txt +10 -2
@@ -12,7 +12,7 @@ SYNOPSIS 'git submodule' [--quiet] add [-b branch] [--] <repository> <path> 'git submodule' [--quiet] status [--cached] [--] [<path>...] 'git submodule' [--quiet] init [--] [<path>...] -'git submodule' [--quiet] update [--init] [-N|--no-fetch] [--] [<path>...] +'git submodule' [--quiet] update [--init] [-N|--no-fetch] [--rebase] [--] [<path>...] 'git submodule' [--quiet] summary [--summary-limit <n>] [commit] [--] [<path>...] 'git submodule' [--quiet] foreach <command> 'git submodule' [--quiet] sync [--] [<path>...]
@@ -113,7 +113,8 @@ init:: update:: Update the registered submodules, i.e. clone missing submodules and checkout the commit specified in the index of the containing repository. - This will make the submodules HEAD be detached. + This will make the submodules HEAD be detached unless '--rebase' is + specified. + If the submodule is not yet initialized, and you just want to use the setting as stored in .gitmodules, you can automatically initialize the
@@ -177,6 +178,13 @@ OPTIONS This option is only valid for the update command. Don't fetch new objects from the remote site. +--rebase:: + This option is only valid for the update command. + Rebase the current branch onto the index of the containing repository + instead of detaching the HEAD. + If a a merge failure prevents this process, you will have to resolve + these failures with linkgit:git-rebase[1]. + <path>...:: Paths to submodule(s). When specified this will restrict the command to only operate on the submodules found at the specified paths.
git-submodule.sh +18 -4
@@ -17,6 +17,7 @@ branch= quiet= cached= nofetch= +rebase= # # print stuff on stdout unless -q was specified
@@ -314,6 +315,10 @@ cmd_update() shift nofetch=1 ;; + -r|--rebase) + shift + rebase=1 + ;; --) shift break
@@ -367,11 +372,20 @@ cmd_update() die "Unable to fetch in submodule path '$path'" fi - (unset GIT_DIR; cd "$path" && - git-checkout $force -q "$sha1") || - die "Unable to checkout '$sha1' in submodule path '$path'" + if test -z "$rebase" + then + command="git-checkout $force -q" + action="checkout" + msg="checked out" + else + command="git-rebase" + action="rebase" + msg="rebased onto" + fi - say "Submodule path '$path': checked out '$sha1'" + (unset GIT_DIR; cd "$path" && $command "$sha1") || + die "Unable to $action '$sha1' in submodule path '$path'" + say "Submodule path '$path': $msg '$sha1'" fi done }
t/t7404-submodule-update.sh new file +79 -0
79 lines not on this page · raw message
Signature · 1 line
1.6.2.2.447.g4afa7
Hi,
Quoted 17 lines · Peter Hutterer
Quoted 10 lines · Johannes Schindelin
Peter wrote originally:
Quoted 8 lines
Documentation/git-submodule.txt +0
-0@@ -177,6 +178,12 @@ OPTIONS This option is only valid for the update command. Don't fetch new objects from the remote site.Quoted 4 lines
Documentation/git-submodule.txt OPTIONS · line 182
Quoted 2 lines
Documentation/git-submodule.txt +2
-0+--rebase:: + This option is only valid for the update command.This is unnecessary, it was mentioned in the synopsis.
Quoted 5 lines
Correct, but in the same file the options --cached, --no-fetch, and --summary-limit do state that they are only valid for the update/status/summary commands, respectively. For consistency, we should either add this sentence to --rebase, or remove them from the others. I personally prefer having it there, just to make it more obvious.
Fair enough!
Quoted 10 lines
Quoted 6 lines
Documentation/git-submodule.txt OPTIONS · line 183
Quoted 1 line
Documentation/git-submodule.txt +1
-0+ Forward-port local commits to the index of the containing repository.This is a bit misleading/unclear. I'd rather have it read like this:
Instead of detaching the HEAD to the revision committed in the superproject, rebase the current branch onto that revision.
Hehe. I had something like this before and then decided to copy/paste the line from the git-rebase man page :)
Quoted 7 lines
Changed to: "Rebase the current branch onto the index of the containing repository instead of detaching the HEAD." (I vaguely remember the rule that sentences are easier to understand if you have "blah instead of foo" rather than "instead of foo, blah")
The phrase "index of the containing repository" is commonly used in this man page, so I think it's best to stick with it. That better now?
Hmm.
You can really rebase only onto a commit. And the index is not a commit, so I do not like the wording (not even in the rebase man page).
But let's see what other reviewers say... :-)
Quoted 14 lines
Quoted 5 lines
Quoted 5 lines
Documentation/git-submodule.txt +3
-0+ If a a merge failure prevents this process, you will have to resolve + these failures with linkgit:git-rebase[1]. + <path>...:: Paths to submodule(s). When specified this will restrict the commandQuoted 8 lines
git-submodule.sh
Quoted 5 lines
Documentation/git-submodule.txt +0
-0to only operate on the submodules found at the specified paths.git-submodule.sh +0
-0You might want to error out when --rebase was passed with another command than "update".
Quoted 3 lines
cmd_init(),cmd_summary(), etc. have catch-all rules for unknown options to display the usage, so this is covered. (e.g. line 439,git-submodule.sh)
Oh, okay!
Other than the wording, I am completely happy with this patch.
Ciao,
Dscho