When calling 'git pull' with the '--rebase' option, it performs a
fetch + rebase instead of a fetch + pull.
This behavior is more desirable than fetch + pull when a topic branch
is ready to be submitted.
fetch + rebase might also be considered a better workflow with shared
repositories in any case, or for contributors to a centrally managed
project, such as Wine -- or Git.
For your convenience, you can set the default behavior for a branch by
defining the config variable branch.<name>.rebase, which is
interpreted as a bool. This setting can be overridden on the command
line by --rebase and --no-rebase.
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
---
Documentation/git-pull.txt | 6 ++++++
git-pull.sh | 11 ++++++++++-
t/t5520-pull.sh | 22 ++++++++++++++++++++++
3 files changed, 38 insertions(+), 1 deletions(-)
diff --git a/Documentation/git-pull.txt b/Documentation/git-pull.txt
index e1eb2c1..c3ce8ee 100644
--- a/Documentation/git-pull.txt
+++ b/Documentation/git-pull.txt
@@ -33,6 +33,12 @@ include::urls-remotes.txt[]
include::merge-strategies.txt[]
+\--rebase::
+ Instead of a merge, perform a rebase after fetching.
+
+\--no-rebase::
+ Override earlier \--rebase.
+
DEFAULT BEHAVIOUR
-----------------
diff --git a/git-pull.sh b/git-pull.sh
index 74bfc16..b5ecb80 100755
--- a/git-pull.sh
+++ b/git-pull.sh
@@ -16,6 +16,9 @@ test -z "$(git ls-files -u)" ||
die "You are in the middle of a conflicted merge."
strategy_args= no_summary= no_commit= squash=
+curr_branch=$(git symbolic-ref -q HEAD)
+curr_branch_short=$(echo "$curr_branch" | sed "s|refs/heads/||")
+rebase=$(git config --bool branch.$curr_branch_short.rebase)
while :
do
case "$1" in
@@ -43,6 +46,12 @@ do
esac
strategy_args="${strategy_args}-s $strategy "
;;
+ -r|--r|--re|--reb|--reba|--rebas|--rebase)
+ rebase=true
+ ;;
+ --no-r|--no-re|--no-reb|--no-reba|--no-rebas|--no-rebase)
+ rebase=false
+ ;;
...I'd like there to be some *big*warning* about how this destroys history and how you must not do this if you expose your history anywhere else. I think it's a perfectly fine history, but if you have already pushed out your history somewhere else, you're now really screwed. In ways that a *real* merge will never screw you. So the "--rebase" option really is only good for the lowest-level developers. And that should be documented. Linus -
Hi, Fair enough. How about this in the man page: \--rebase:: Instead of a merge, perform a rebase after fetching. *NOTE:* Never do this on branches you plan to publish! This command will _destroy_ history, and is thus only suitable for topic branches to be submitted to another committer. Ciao, Dscho -
Reasonable, although perhaps it should mention what I suspect might be a common workflow for this feature: CVS emulation. I.e., there is a central repo, which is the only thing considered "published". Developers make commits in their local repo, and then rebase their changes onto the HEAD before pushing. The only difference from CVS is that you don't actually get to commit in CVS, you have to do the rebase with your working tree. :) I'm imagining a "pull.rebase = 1" config option, and handing this out to developers accustomed to CVS. -Peff -
Actually, I think I've just restated Junio's comment somewhat, so the change you made in response to him is an improvement. Sorry for the noise. -Peff -
Nits.
(1) This "operation" will "rewrite" history.
You are not describing a command, but just one mode of operation
of a command, whose other modes of operation do not share this
history altering behaviour.
The history is rewritten and made hard to work with for others
who have previous incarnation of that history. If it happens
that nobody shared that previously published history nobody
needs to suffer. In that sense, there is something _usable_
depending on who you are. Destroy feels a bit too strong a
word.
(2) This is not suitable for people who publish their trees and
let others fetch and work off of them.
Rebase is fine for e-mail submitting contributors as your
description above suggests, but as your proposed commit log
message said, it is also perfectly appropriate if your
interaction with the outside world is "fetch + rebase +
push". You are not limited to "submitted to another
committer".
-
Hi,
Well, originally I did not want to document it at all. But I already
heard the complaints about that in my inner ear. So I documented it,
sparsely, in the hope that those who do not know the implications will not
dare to use it. After Linus' complaint, I tried to make this shooing away
more explicit.
I do not want to go into _that_ many details here, since the place to look
for it is git-rebase.txt. Probably I should have done that in the first
place.
So how about this instead:
\--rebase::
Instead of a merge, perform a rebase after fetching.
*NOTE:* This is a potentially _dangerous_ mode of operation.
It rewrites history, which does not bode well when you
published that history already. Do _not_ use this option
unless you have read gitlink:git-rebase[1] carefully.
Hmm?
Ciao,
Dscho
-
When calling 'git pull' with the '--rebase' option, it performs a fetch + rebase instead of a fetch + pull. This behavior is more desirable than fetch + pull when a topic branch is ready to be submitted and needs to be update. fetch + rebase might also be considered a better workflow with shared repositories in any case, or for contributors to a centrally managed repository, such as WINE's. As a convenience, you can set the default behavior for a branch by defining the config variable branch.<name>.rebase, which is interpreted as a bool. This setting can be overridden on the command line by --rebase and --no-rebase. Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de> --- On Tue, 27 Nov 2007, Junio C Hamano wrote: > Johannes Schindelin <Johannes.Schindelin@gmx.de> writes: > > > ... > > I do not want to go into _that_ many details here, since the > > place to look for it is git-rebase.txt. Probably I should > > have done that in the first place. > > > > So how about this instead: > > > > \--rebase:: > > Instead of a merge, perform a rebase after fetching. > > *NOTE:* This is a potentially _dangerous_ mode of operation. > > It rewrites history, which does not bode well when you > > published that history already. Do _not_ use this option > > unless you have read gitlink:git-rebase[1] carefully. > > > > Hmm? > > Okay. I also added documentation for the branch.<name>.rebase variable. Documentation/config.txt | 7 +++++++ Documentation/git-pull.txt | 10 ++++++++++ git-pull.sh | 11 ++++++++++- t/t5520-pull.sh | 22 ++++++++++++++++++++++ 4 files changed, 49 insertions(+), 1 deletions(-) diff --git a/Documentation/config.txt b/Documentation/config.txt index 645514d..7bebc9a 100644 --- a/Documentation/config.txt +++ b/Documentation/config.txt @@ -360,6 +360,13 @@ branch.<name>.mergeoptions:: option values containing whitespace characters are currently not ...
Don't you mean fetch + merge ? -
Hi, Obviously. Thanks, Dscho -
I wonder if this shouldn't be branch.<name>.pulltype or something like that, so we can represent more than just "rebase or not." Values could be "rebase", "merge" (the default) and maybe even "manual" to specify that git-pull should neither merge nor rebase a particular branch even if it matches a wildcard refspec. Not too sure about that last suggestion but it seems like there might be other settings than "rebase" and "merge" in the future even if that's not one of them. -Steve -
Hi, I am not convinced that this is a good thing... We already have branch.<name>.mergeOptions for proper merges, and I want to make clear that this is about rebase, and not about merge. Ciao, Dscho -
Maybe branch.<name>.pullOptions ? -- larsh -
Maybe not make this part of git-pull at all? merge and rebase have totally different impact on the resulting history, so perhaps a separate command that is a shorthand for "git fetch && git rebase" may help unconfuse the users. -
Hi, Not so sure about that. We already have too many commands, according to some outspoken people, and this would add to it. Besides, the operation "pull" is about getting remote changes incorporated in your current branch. IMHO "pull = fetch + merge" is only a technical detail, and we should not be bound by it too much. Ciao, Dscho -
Yeah, I agree. I almost never use "pull" as is because I almost always want to rebase. That is, it's basically clutter for me as a command right now, and it would remain so even if a separate fetch+rebase command were added. I think this may be a difference in perspective based on how one uses git. If I were an integrator I would probably use "pull" as is a lot more because I would want the merges represented explicitly in my history. But most of the time I'm working as a leaf node in the tree of repositories, interacting only with a central integration repo, and I basically never want a give-me-the-remote-changes operation (which is really more of a "sync me up with the latest changes from the rest of the team" operation) to put a merge in my history. What's more, when I'm introducing git to new people in my environment, right now I tell them about fetch and rebase and pretty much have to tell them to avoid running "pull" until they're comfortable with git, since I know their histories would be full of meaningless merges otherwise. It'd be nice to have new people run one less command as part of their normal day-to-day work. -Steve -
What they're really complaining about is the size and complexity of the interface, and the lack of a clearly identified subset for them to learn first. This has so far mainly manifested itself in complaints about the number of commands, because that's currently where a lot of our complexity is. But they *will* complain about proliferation of commandline switches and config options too. (I've heard complaints about the number of switches required on the average cvs commandline, for example.) We're stuck expanding the interface here, whether we expand it by another command or another commandline switch. So, how do you decide whether to make it a new command or not? - Look at existing documentation that talks about pull: if that documentation will still apply to the new pull, that weighs for keeping it the same command. If theat documentation would apply only without having a certain config value set, then I think it's better as a separate command. - Will this make it more or less simple to identify the subset of the git syntax that a user will have to do a given job? If there are jobs for which someone might only ever need the new fetch+rebase, or for which they would only ever need the traditional pull, then I think it would keep the two separate, to make it easier for a learner to skip over information about the one they're not using. I've got no proposal for an alternate name. All that comes to mind is the portmanteau "freebase", which is terrible.... --b. -
Actually, considering the second point: people that are using fetch+rebase don't necessarily need or (for now) want to understand pull at all. But they certainly *do* have to understand rebase. Would it be possible to add this to rebase instead of to pull? git rebase --url git://x.org/x.git master where --url means "interpret <upstream> as a branch from the given remote repository. That interacts poorly with --onto, though. --b. -
Hi, I was briefly considering it. But the point is this: I know exactly if I want to rebase my branch onto upstream, or if I want to merge it. There is not much point in mixing the two. So my rationale was: if we already have an existing framework to integrate remote changes with our current branch, why not just go ahead and use it? That's the reason BTW why I originally wanted a "rebase" merge stragegy. Even if it is not technically a merge. I really rather have no user-friendly support for fetch+rebase (and utter a friendly, but loud curse everytime I made a "git pull" by mistake) than yet another command. Ciao, Dscho -
I suspect that people who do not like the two modes of checkout will certainly not appreciate the overloading two behaviours to create different kind of histories and two different ways to continue when the integration do not go smoothly upon conflicts these two behaviours have. However, I agree very much with an earlier comment made by Daniel about our UI being task oriented instead of being command oriented, and I actually consider it a good thing. So it does not bother me too much that "git pull --rebase" has a quite different workflow from the regular "merge" kind of pull. So let's queue "pull --rebase" and see what happens. -
What I'm really most worried about isn't the commandline switch but the config option--it makes the same commandlines silently behave in very different ways. I really don't want every tutorial that mentions "git pull" to have to say "the following applies only if git.<current-branch>.rebase is false". And it'll be either that or risk having a lot of people saying "I typed in exactly that commandline, but this happened....". A default to "false" does at least require positive acknowledgement, but if this is expected to be used by newbies, they're going to be told to set that config before they understand the difference it makes. --b. -
Hi, Hey, why not just special case "mergeOptions = rebaseInstead"? Ciao, Dscho -
I've used the --rebase option to git pull, explained it to my co-workers and also made sure they're using a version of git that has it. So far there hasn't been a single complaint about "git pull" being any harder to grok. -- Andreas Ericsson andreas.ericsson@op5.se OP5 AB www.op5.se Tel: +46 8-230225 Fax: +46 8-230231 -
Well, the idea is that once all those plumbing commands are hidden away in some libexec dir, that makes a _lot_ of breathing room for a few more porcelain commands if needed. Nicolas -
At long last, we can revive "git update"! jdl -
Hi, No, we cannot. By now, too many aliases are called "update". Ciao, Dscho -
Hm, why not tackle the whole thing the other way around? IMHO the primary action is the merge/rebase, not the fetch. So choosing which action you want in addition to the fetch seems a bit backwards. git-svn already includes a fetch from svn in its rebase operation, which is really handy, because you rebase quite often with that beast. And it's likely that you want to merge with/rebase against the latest available remote commit all the time anyway and on the few(?) occassions where you have no connectivity, but already fetched some remote stuff which you want to incorporate into your local branches now, it's hopefully bearable to pass --no-fetch. So how about adding --fetch/--no-fetch (maybe with a configurable default?) to git-merge/git-rebase and deprecate git-pull over time? Björn -
FWIW, I like this idea. rebase/merge is the complicated part of the operation, so the UI should focus on that. Updating or not updating the remote-tracking branch that is merged from/rebased on is a simple binary choice, so a flag is perfect. -- Karl Hasselström, kha@treskal.com www.treskal.com/kalle -
Well, it really needs explanation of what "destroy" means. Also, it's not strictly even necessary to publish things for this to cause problems. It's perfectly sufficient to just do development on two private developer machines, and do things like keeping the two machines in sync by pulling things between them manually... So even "normal" developers who never publish a git tree to others may actually hit this issue. Linus -
.. or any branch use, for that matter. I do agree that "git merge --rebase" is potentially convenient, I'm just not sure it's a great idea to document as such. People shouldn't do it unless they really *really* understand the implications, and I think the implications are much easier to understand if you instead teach them "fetch+rebase", and perhaps even keep the "merge --rebase" option entirely undocumented. Linus -
