|
|
Log in / Subscribe / Register

Git project seeks discussion on "push" change

From:  Junio C Hamano <gitster-AT-pobox.com>
To:  info-AT-lwn.net
Subject:  Requesting dissemination of RFD on "git push" default
Date:  Fri, 16 Mar 2012 22:10:51 -0700
Message-ID:  <7vzkbfdd7o.fsf@alter.siamese.dyndns.org>

There is a proposal to change the default behaviour of 'git push' on the
Git mailing list, primarily to help new people who are used to central
shared repository workflow.  As this may negatively affect long time users
of the tool, we are trying to reach as many such users as possible with
the attached note to request their participation in the discussion.

Could you kindly devote one news item on the LWN.net site please?

-- >8 -- -- >8 -- -- >8 -- cut here -- >8 -- -- >8 -- -- >8 -- 

There is a proposal to change the default behaviour of 'git push' on the
Git mailing list. The goal of this message is to encourage you to discuss
it before it happens (or the change is aborted, depending on the outcome
of the discussion).

In the current setting (i.e. push.default=matching), 'git push' without
argument will push all branches that exist locally and remotely with the
same name. This is usually appropriate when a developer pushes to his own
public repository, but may be confusing if not dangerous when using a
shared repository. The proposal is to change the default to 'upstream',
i.e. push only the current branch, and push it to the branch 'git pull'
would pull from. Another candidate is 'current'; this pushes only the
current branch to the remote branch of the same name.

For more details on the behavior of Git with these values, read the
documentation about 'push.default' in 'man git-config'
(http://schacon.github.com/git/git-config.html).

You may be negatively affected when such a change happens if you do not
see anything in the output from 'git config push.default' and if you rely
on the default that pushes all your matching branches. On the other hand,
you may want to see the default behaviour to change, especially if you are
using shared repositories. In either case, please join the discussion to
give us more data point and help us decide the future of Git. Also, if
you think your friends and colleagues will be affected by this change,
either positively or negatively, please tell them about this discussion.

What has been discussed so far can be seen in this thread:

    http://thread.gmane.org/gmane.comp.version-control.git/19...

Previous relevant discussions include:

    http://thread.gmane.org/gmane.comp.version-control.git/12...
    http://thread.gmane.org/gmane.comp.version-control.git/16...

To join the discussion, send your messages to:

    git@vger.kernel.org

The list accepts messages from non-subscribers, and you do not have to ask
"please Cc me, I am not subscribed", as it's customary to Cc: posters when
replying on this list.




to post comments

Good idea!

Posted Mar 19, 2012 15:24 UTC (Mon) by dskoll (subscriber, #1630) [Link] (5 responses)

IMO, this is a much more sensible default. I just went in and changed my .gitconfig to specify push.default = upstream.

Good idea!

Posted Mar 19, 2012 15:26 UTC (Mon) by dskoll (subscriber, #1630) [Link]

err... I had to use tracking rather than upstream because I'm still running 1.7.2.5, but the principle is the same.

Good idea!

Posted Mar 19, 2012 16:03 UTC (Mon) by danieldk (guest, #27876) [Link] (2 responses)

Indeed, I always disliked the standard push behavior, but was (apparently) too lazy to find this option.

Good idea!

Posted Mar 19, 2012 16:38 UTC (Mon) by aorth (subscriber, #55260) [Link]

I agree, I think 'upstream' is a more sensible default. I was always confused by the default behavior... this helps. :)

git option documentation

Posted Mar 19, 2012 17:13 UTC (Mon) by ballombe (subscriber, #9523) [Link]

You are not too lazy.

Options for 'git foo' should be documented in 'git help foo', but this is often not the case. Instead push.default is only documented in 'git help config', so basically you will not find about it unless you know it exists.

If options were documented properly, there would probably be less complains about default behaviors.

Good idea!

Posted Mar 19, 2012 19:25 UTC (Mon) by xxiao (guest, #9631) [Link]

+1 on this. please set up it as default(i.e. upstream) asap.

Git project seeks discussion on "push" change

Posted Mar 19, 2012 16:03 UTC (Mon) by loftsy (guest, #75160) [Link]

Wow... this change makes it much more useful. I'd always wondered what git push with no arguments actually did.

pull --rebase

Posted Mar 19, 2012 16:06 UTC (Mon) by rwmj (subscriber, #5474) [Link] (19 responses)

(Dons flame-proof suit)

It'd be great if the default for 'git pull' was to rebase
instead of merge ...

Rich.

pull --rebase

Posted Mar 19, 2012 16:43 UTC (Mon) by dskoll (subscriber, #1630) [Link]

I agree and I've configured my git to do that:

branch.autosetuprebase = always

pull --rebase

Posted Mar 19, 2012 17:08 UTC (Mon) by slashdot (guest, #22014) [Link]

Seconded.

Rebase is the best option for work in progress or just unpublished commits, and that's what you almost always have if you are using "git pull" instead of "git merge" (well, not having any commit is even more likely, but there's no difference in that case).

pull --rebase

Posted Mar 19, 2012 22:36 UTC (Mon) by Anssi (subscriber, #52242) [Link] (14 responses)

I agree. If I want merges, I run 'merge' explicitely. Also, something like this should make the useless merge commits I often see in git repositories (when they have users new to git pushing stuff) completely disappear.

This seems such an obvious change to me, though, that there probably is some good reason why it hasn't been done already...

One potential issue that I can think of is that after such a change it would be easier to rewrite history. However, most histories are unpublished anyway, and git-push already rejects actually publishing a rewritten history, which should be enough I think.

Also, it would be a kind of big behavioural change... If that is an issue, maybe the "git pull" and "git pull --rebase" commands should be completely separated to different commands?

pull --rebase

Posted Mar 20, 2012 0:46 UTC (Tue) by dlang (guest, #313) [Link] (13 responses)

rebasing means that you end up with a new version of code that you have never tested, and it's impossible for anyone looking at the resulting tree to figure out what you developed against.

The 'right' way to do things is to have a branch that you use to track the upstream version, one or more branches that you do development in, and then you create test branches to test merging your work with the upstream work (rather than merging directly into your development or upstream branches). After you test the merge, you delete the branch, you defiantly don't do any more development on it.

only when you are ready to push do you do a merge that will be visible to the outside world and push out.

the excess merge commits that you are bothered by are an indication of real problems, but rebasing instead isn't any better.

pull --rebase

Posted Mar 20, 2012 0:54 UTC (Tue) by dskoll (subscriber, #1630) [Link] (1 responses)

The 'right' way to do things depends on your development team's workflow and the project you're working on. For my main project with only a couple of developers, pull --rebase is almost always the 'right' thing to do.

pull --rebase

Posted Mar 20, 2012 1:10 UTC (Tue) by dlang (guest, #313) [Link]

quoting Anssi:

> This seems such an obvious change to me, though, that there probably is some good reason why it hasn't been done already..

I was providing the reason why it's not such an obvious change.

pull --rebase

Posted Mar 20, 2012 1:21 UTC (Tue) by Anssi (subscriber, #52242) [Link]

Right. I guess majority of my pushes are smallish single-commit ones, which IMHO do not warrant visible merges (I guess this depends a bit on the project and the workflow, though). For bigger stuff I normally do what you desribed (though often they don't get visible merges either, if I send them via email to upstream who then uses git am).

And after thinking about this a bit more, while I run "git pull --rebase" very often, most times it is on the upstream-tracking branch so "git pull" should actually work just the same.

That is, unless I've made some quick fix commit in the upstream-tracking branch before send-emailing it (when I've forgotten to create a branch for it), in which case "git pull" would do a merge while "git pull --rebase" would usually drop the local one. As said, though, that shouldn't happen :)

pull --rebase

Posted Mar 20, 2012 10:57 UTC (Tue) by adobriyan (subscriber, #30858) [Link] (5 responses)

> rebasing means that you end up with a new version of code that you have never tested

If rebased code is the same as merged code, yes, it was tested.

pull --rebase

Posted Mar 20, 2012 12:56 UTC (Tue) by nevets (subscriber, #11875) [Link] (3 responses)

> If rebased code is the same as merged code, yes, it was tested.

But that's the big "If". When I first started using git, the upstream maintainer use to rebase my changes into his tree. The problem I had was I never knew what changes he pulled. I would push out a patch series of commits but I never knew what patches actually made it upstream. This changed later when Linus told everyone how to do it, and my push requests were then merged.

The problem is that I can not check what patches I pushed actually made it into upstream. There were some cases that a patch or two was dropped, and I had no clue. It was dropped because of conflicts or someone questioned the patch. But because the other patches were rebased in, I had to go patch by patch to determine what was in and what was not, and this was very time consuming.

I totally understand the usefulness of git pull being a rebase, but it should not be the default. Could you imagine Linux if Linus rebased everyone's pull requests?

pull --rebase

Posted Mar 20, 2012 21:38 UTC (Tue) by mathstuf (subscriber, #69389) [Link] (2 responses)

Unless I'm sorely mistaken, pull --rebase doesn't rebase pulled branches onto another branch. Instead, it rebases any changes that you have locally that are on a branch onto whatever you pulled down from the remote for that branch. The only problem I've encountered with this when I've made merges into master or next and pulling rebases the merge on top of the tree. A pull --rebase should probably pass -p to rebase so that merges are re-merged instead of streamlined on the branch.

pull --rebase

Posted Mar 20, 2012 22:30 UTC (Tue) by nevets (subscriber, #11875) [Link] (1 responses)

You may not be mistaken, I may be. I've never used a pull --rebase before, as that's not part of my workflow.

My workflow would be to do a git remote update of the repo that I'm going to base my work on, and then start adding commits to it. Then push those changes upstream.

The repos I take changes from, I do a pull from others, which I do not want to have any rebase (mine or theirs). If you pull from multiple people, how would this work? One pull would rebase against the other.

If I have old commits and want to rebase them on the latest upstream, I simply do a git remote update of the upstream branch and then do a local rebase.

Now I'm confused to the purpose of pull --rebase?

pull --rebase

Posted Mar 20, 2012 23:14 UTC (Tue) by mathstuf (subscriber, #69389) [Link]

Suppose you have two machines with different commits on some branch. You push from one machine to a common remote repository. On the other machine, you need to pull.

Before:

--B--R (origin/branch)


--B--L (branch)

pull --merge:

--B--R
      \
       \
--B--L--R'

pull --rebase:

--B--R
     | (fast-forward merge on top of B, then rebase L on top of R)
     |
--B--R--L'
The problem is that pull --merge creates a merge commit on the branch with "itself". These commits are, IMNSHO, ugly and shouldn't happen. Now what happens if L is some topic branch that got merged into the branch?
Before:

--B--R (origin/branch)


--B-----L (branch)
       /
      /
--S--T (topic)

pull --rebase (no -p flag):

--B--R
     |
     |
--B--R--S'--T'

pull --rebase (with -p flag):

--B--R
     |
     |
--B--R--L'
       /
      /
--S--T

With the -p flag, pulling from the remote, keeps the repository looking most similar to what it did before the pull which is one reason why I like it more. The other is that I believe that feature branch merges should *always* use --no-ff so that reverting them is easy (reverting L' is easy; S' and T' less so, especially if topic will land later at some point and it's just broken now).

As for multiple remotes sharing a single branch name, all I can say is that I prefer to not do that. I name remotes in namespaces for non-origin repositories (so foobar's github clone is the gh/foobar remote and I checkout foobar's branches as foobar/branchname). Even my forks get named gh/mathstuf on my machines so that if I keep a personal master branch (mathstuf/master) with my feature branches merged in, it doesn't conflict with the actual master branch. My personal feature branches get named under the dev/ namespace and are not under a username. If they become collaborative, then I'd start namespacing them.

pull --rebase

Posted Mar 21, 2012 15:42 UTC (Wed) by misiu_mp (guest, #41936) [Link]

Yes, you should test the code after a rebase as well as after a merge, but, as we all know testing is not always bullet proof. Part of the testing is code review, including the one you do when you modify the existing code.
Take the following history:
A - B - C - D - H
      \       /
        F - G
you implement a feature (F, G) starting from version B.
In order to implement the feature, you have to investigate and understand how the existing code works. When you do that you see version B and the history above accurately depicts it.
Now imagine C introduces a change that affects the code you analyzed in a logical, non-trivial way (that does not introduce a merge conflict with your feature). Your feature will now behave incorrectly, but in a very subtle way. If you based your feature off C or D, you would have probably analyzed the code correctly and made a correct implementation. But you didn't. You maybe just quickly review the changes in C and D, run tests and push to H, merging without conflicts. The tests didn't pick up the subtle error and you've got a bastard-of-a-bug, which depends on a simultaneous modification in two branches, but not in each separately.
If you rebase, the other branch disappears and the history looks as if you indeed started your work after C, indicating you should have seen the changed behavior and its code.
A - B - C - D - F - G
After the bug was found it will be much more difficult for anyone, including you to realize what happened. The lack of rebasing would not prevent the bug, but it would make it easier to track and fix.

pull --rebase

Posted Mar 20, 2012 17:12 UTC (Tue) by njs (subscriber, #40338) [Link] (2 responses)

> After you test the merge, you delete the branch, you defiantly don't do any more development on it.
> only when you are ready to push do you do a merge that will be visible to the outside world and push out.

I've seen people saying this for a while and it completely baffles me. Maybe you can explain.

What's so bad about merging from time-to-time as you work on your branch? That way you're sticking closer to upstream, can handle any changes and testing incrementally, and don't have to repeat merges over and over. I know it can work -- we did this all the time in monotone (the predecessor to git and hg), and it was wonderful. You end up with extra merges recorded in history, but who cares... they happened... they let future merges work better... instead we have kluges like git-rerere that try to tack a fake merge tool onto a system that already has a real one.

Back in the CVS days the inability to track merges into branches was considered one of the biggest bugs. Now that we fixed it, everyone seems to think that was actually a feature. Why?

pull --rebase

Posted Mar 20, 2012 18:39 UTC (Tue) by dlang (guest, #313) [Link]

I'm not really a good person to explain the reasons behind this. I'm just passing on what I have learned from watching the discussions on the various discussion lists (especially the kernel and git lists)

I agree it sounds like it should improve development, but as I understand it, the actual result is that it complicates matters because you are pulling in unrelated changes with each merge. These unrelated changes may cause other problems along the way.

I suspect that how big an issue this is depends on the scope of the changes you are making.

If you are working on global-scale changes that touch lots of places, keeping up with upstream changes is more important, and just about all changes are relevant to the work that you are doing.

If you are working on a subsystem that is (relatively speaking) a small portion of the whole, then there are fewer benefits and more drawbacks.

pull --rebase

Posted Mar 21, 2012 16:03 UTC (Wed) by misiu_mp (guest, #41936) [Link]

Here is how I see it: everybody likes a nice linear history. Fat trees with lots of merges are difficult to follow and thus not so useful, which is a good reason to merge less, at least in the public history.
The test-merge way of working is one way to do it: you make modifications, test-merge, make modifications, test-merge, make more modifications and perhaps make a final merge or even rebase.
That would be fine if nothing relevant happened during those merges, so that you could have just as well not made them.
I agree with you though, that relevant merges, where you needed to fix or change something, could (should?) stay in the history.
As usual moderation should be the way to go. The great thing about git is that you have a choice.

pull --rebase

Posted Mar 21, 2012 14:12 UTC (Wed) by slashdot (guest, #22014) [Link]

If you are actively developing the code, rebase is correct because you'll test it against the new upstream code as part of normal development.

If you aren't actively developing it, then you should have it published already, and thus merge is correct.

pull and push

Posted Mar 20, 2012 14:44 UTC (Tue) by jengelh (subscriber, #33263) [Link]

>It'd be great if the default for 'git pull' was to rebase

(Echo coming back to you:) It'd be great if pull actually did fetch rather than merge. (For going in line with being the antonym of push.)

pull --rebase

Posted Mar 21, 2012 23:05 UTC (Wed) by man_ls (guest, #15091) [Link]

Fourthed (or fifthed, lost count). As a git newbie I have always wondered about those stray merges and why git didn't do the right thing -- I didn't even know about --rebase until now, thanks!

Is it completely safe to use though? I am afraid that my commits will grow long hair and learn to play banjo after a pull --rebase.

Git project seeks discussion on "push" change

Posted Mar 19, 2012 16:17 UTC (Mon) by nas (subscriber, #17) [Link]

That change is totally fine with me. I always explicitly name the remote branch, probably because I don't like the "push everything" default behavior.

It would be nice if git had some mechanism for this type of change. For example, if somehow the user could be prompted on upgrade about the new behavior. That would allow faster evolution of git to more sane defaults (things are mostly okay already but still is room for improvement).

Git project seeks discussion on "push" change

Posted Mar 19, 2012 17:42 UTC (Mon) by spaetz (guest, #32870) [Link]

change is sensible. +1

+1

Posted Mar 19, 2012 18:22 UTC (Mon) by pferreir (guest, #83556) [Link]

I support this.

Git project seeks discussion on "push" change

Posted Mar 19, 2012 18:50 UTC (Mon) by tihuinc (guest, #83559) [Link]

The current behavior has caused me and my team much grieve when new git team member accidentally pushed to production branch and deployed afterwards.

The suggested behavior is much more sensible given the option to set up "push to all branches" in git config, which implies the user ACTUALLY wants that behavior.

+1 on this.

Git project seeks discussion on "push" change

Posted Mar 19, 2012 19:24 UTC (Mon) by jimparis (guest, #38647) [Link]

+1 sounds good

+0

Posted Mar 19, 2012 20:53 UTC (Mon) by smurf (subscriber, #17840) [Link]

I don't actually have any writeable upstream repositories without push= entries, so this change won't afect me at all.

Still, I suppose it makes sense.

Git project seeks discussion on "push" change

Posted Mar 20, 2012 3:27 UTC (Tue) by dwon (subscriber, #54223) [Link] (1 responses)

+1 for "upstream".

-1 for "pull --rebase" by default (mentioned in another lwn thread). Rebase can make an awful mess, so it should never be done without the user's knowledge (either using the --rebase option, or using ~/.gitconfig).

Git project seeks discussion on "push" change

Posted Mar 20, 2012 18:03 UTC (Tue) by destok (guest, #83600) [Link]

I fully agree :

+1 for "upstream".
-1 for "pull --rebase"

Git project seeks discussion on "push" change

Posted Mar 20, 2012 6:55 UTC (Tue) by mordae (guest, #54701) [Link]

+1 I've always ran git in push.default=tracking mode. Basically from the day one. If I want to push some other branch, I make it track the destination first.

Git project seeks discussion on "push" change

Posted Mar 20, 2012 7:35 UTC (Tue) by bergwolf (guest, #55931) [Link] (3 responses)

I'd rather suggest disabling git push without any options. It is uncontrollable to just type "git push" and hoping git to do all the magic for you.

As an alternative, I always use "git push [local]:<remote>". Forcing the syntax is making more sense than changing the default behavior from time to time.

Git project seeks discussion on "push" change

Posted Mar 20, 2012 13:32 UTC (Tue) by ekj (guest, #1524) [Link]

Yes. What git needs is commands that take a bunch of arguments where you specify everything for everyday routine commands. Because the learning-curve isn't nearly steep enough as it is.

Git project seeks discussion on "push" change

Posted Mar 20, 2012 18:54 UTC (Tue) by fragmede (guest, #50925) [Link]

+1 to making pain "git push" a nop.

A question I'm often asked is how the local branch name can different from the remote branch name, which is what this syntax is for. It also makes it easier to remember that "git push :<remote>" deletes the remote branch, and ":" isn't some randomly chosen character to delete remote things.

It's just a shame that the git push local:remote syntax is so high up on the learning cliff that many git users don't know about it.

Git project seeks discussion on "push" change

Posted Mar 21, 2012 6:01 UTC (Wed) by cpeterso (guest, #305) [Link]

Does push.default=nothing do what you want?

http://techbase.kde.org/Development/Git/Configuration#Push_Default

This option forces you to always enter the name of the remote branch you wish to push to, rather than using a default value. This is good practice as it ensures you push to the correct remote branch and avoid accidentally pushing all local branches to the remote.

Git project seeks discussion on "push" change

Posted Mar 20, 2012 8:18 UTC (Tue) by aneeshpu (guest, #83581) [Link]

+1.
I usually change push.default to current or name the branch explicitly while pushing

Git project seeks discussion on "push" change

Posted Mar 20, 2012 12:59 UTC (Tue) by nevets (subscriber, #11875) [Link]

I hated the default. Every git repo that I have has a "push" remote and I have a script called "push-this-branch" which finds out what branch its on and does:

git push push <this-branch>

Git project seeks discussion on "push" change

Posted Mar 20, 2012 13:07 UTC (Tue) by nevets (subscriber, #11875) [Link]

If you really want to let *everyone* know about this change, then have 'git push' with no parameters tell the user with the following message:

git push has changed the push command. It no longer defaults to ...
Do you want to keep the old default [y/N] N
Do you want to show this message again [y/N] N

Basically, have a warning that tells the user the change that is doing and ask the user if they want to keep the old default. If they do, then update the config to have git push stay the same.

Then ask the user if they want to see this message again, and if they say no, then update the config to not show the message.

I know now you are just trying to figure out if the change is good or not. But to make all users find out about this change, this intrusive message will do the trick. It may break a script here or there, but once the user says not to show the message, it will no longer be an issue.

Git project seeks discussion on "push" change

Posted Mar 20, 2012 16:35 UTC (Tue) by coleb (guest, #83592) [Link]

I didn't realize there was an "upstream" option like this or I would have mandated it be the default in our organization. I can't tell you how many times I've been called over to someone's office because, "my push didn't work, but it actually appeared to work". Changing this default will definitely make my life easier.

Git project seeks discussion on "push" change

Posted Mar 20, 2012 16:49 UTC (Tue) by newalexandria (guest, #83593) [Link]

All gratefulness for the change - but... it's about time.

This also helps tremendously in devops automation. It was very annoy to keep passing around (or determine) branch state from one atomic / independent script to the next – all because git doesn't push upstream only be default.

Git project seeks discussion on "push" change

Posted Mar 20, 2012 22:45 UTC (Tue) by gmallard (guest, #83613) [Link]

+0

This will not affect me in any way at present.

Git project seeks discussion on "push" change

Posted Mar 21, 2012 4:07 UTC (Wed) by aaronjensen (guest, #83620) [Link]

+1

Yes, this is an obviously needed change. I also agree with the proposal to make pull rebase by default.


Copyright © 2012, Eklektix, Inc.
Comments and public postings are copyrighted by their creators.
Linux is a registered trademark of Linus Torvalds