git/list[1] front-page[2] threads[3] people[4] search[5] about
 

Re: [PATCH 10/10] push: teach push to be quiet if local ref is strict subset of remote ref

From
Steffen Prohaska <prohaska@zib.de>
Date
Nov 1, 2007, 07:03 UTC
Message-ID
<6B0CD829-A964-410B-8C23-74D26BD2C0FA@zib.de>
In-Reply-To
<7vlk9jgeee.fsf@gitster.siamese.dyndns.org>
On Oct 31, 2007, at 10:31 PM, Junio C Hamano wrote:
Show 18 quoted lines
> Steffen Prohaska <prohaska@zib.de> writes:
>
>>> You forgot a lot more important part.  Pushing into publishing
>>> repositories.  And the discussion is about git-push command.
>>
>> Exactly, here are two examples:
>>
>> If you push only to publishing repositories that are read
>> only by others, you'll never encounter the problem that
>> 10/10 tried to solve. The publishing repository is never
>> changed by others. You are the only one who pushes to this
>> repository. Therefore the remote never advances unexpectedly.
>
> Wrong.
>
> People can and do work from more than one private repositories
> (I do).  In a sense, that is sharing the repository with
> oneself.

I do, too. But as long as I do not forget what I've done, the branches do not advance _unexpectedly_. I am in full control.

Show 12 quoted lines
> I may do an emergency patch to fix breakage on 'maint' (and
> 'maint' only) from a location that is not my primary development
> box and push the fix out.  I fully expect that the push will
> push out 'maint' and expect the other branches such as 'master'
> on the remote side to stay the same, as I haven't touched
> 'master' on that box for quite a while and it is now stale.  In
> that situation, I _want_ the "git push" itself to report failure
> to notify me that it did not push what _I_ asked it to push out,
> so that I can be reminded that I'd better do "git push $remote
> maint" the next time.  In the meantime, even though it reports
> a failure, 'master' on the remote side is _not_ updated, so the
> behaviour is still _safe_.
You're right it is safe, but it may be confusing.
Show 10 quoted lines
>> Another difference is the way changes are integrated. In
>> a workflow without shared repositories, only pull is used
>> for integration, while push in only used for publishing the
>> changes.
>
> Wrong.  push is a mirror of fetch and does not do _any_
> integration.  It is just a safe (because it insists on
> fast-forward) propagation mechanism.  Your integration still
> happens with pull (actually, shared repository people seem to
> prefer "fetch + rebase" over "pull" which is "fetch + merge").

Right; but you can't push without doing the integration. If you have new changes on the remote side you _must_ pull before you can push. You're forced to do the integration immediately. Your main objective was to push, but the shared workflow forces you to do the integration _now_ (by using pull). In a pull-only workflow, you can just push and defere the integration for later.

Some people claim fetch + rebase is superior to fetch + merge. The only point I can see is that fetch + rebase gives a linear history without loops, which is nicer to visualize. I recently asked on the list if there are any benefits of fetch + rebase over fetch + merge, besides a nicer visualization. I didn't receive many interesting comments. One comment explained that rebase can shift the merge conflict resolution from the maintainer (merge) to the original author (rebase). But this is not very interesting in a shared workflow, because the author must resolve conflicts in any case before he can push. It doesn't matter much if he uses merge or rebase to do so.

I evaluated if teaching people fetch + rebase before teaching fetch + merge is a good idea. Therefore I tested some scenarios with people who are new to git. The result is that there are too many situations where fetch + rebase might be confusing. I abandoned my idea.

I decided that fetch + merge is _easier_. It works in all situations, it's easier to explain, it's better supported (automerge), it can be used to work on shared topic branches. Definitely fetch + merge is the first workflow you should learn. At the moment I'm not anymore interested in the fetch + rebase approach.

Show 11 quoted lines
>> This is different if you work with a shared repository. Bob
>> checks out the shared branch foo to his local branch bar and
>> later he needs to push bar back to the shared branch foo. Bob
>> needs to push changes from his local branch bar to the branch
>> foo in the remote repository, a branch with a different name.
>> This need does not emerge when working with two publishing
>> repositories, as described above.
>
> So you do "git push $remote bar:foo".  If you do that regulary,
> there are configuration mechanisms to help you reduce your
> keyboard wear.  What's the problem?
Too complex and not flexible enough.

The configuration is in the remote section. Therefore I can tell git what to do only on a per-branch basis. What do you think about my recent proposal to add branch.$name.push?

And I want to avoid that people need to learn about the details of the configuration mechanism on the first time they use git.

I am searching for a solution that just works for them. They currently use CVS. I'll give them a detailed getting started document for git. The workflow described should be as simple as possible, but safe and reliable. No confusing error messages should appear. Only a few commands should be needed to contribute to a shared branch. The workflow described should use git in a sane way that provides opportunities to use more of its power later.

So here is what I'd like to have.
    git clone ssh://server/git/project.git project
    [ On Windows the hassel already starts because it actually is
	git clone -n ssh://sever/git/project.git project
	git config core.autocrlf true
      And here's the next point. git config doesn't validate the
      variable. It accepts _any_ variable. If you have a typo
      you go without autocrlf. ... but this is a different story. ]
    cd project
    git checkout -b devel origin/devel
    # work, commit, work, commit
    git push  # maybe git pull first, but git would tell you

The last command, git push, can already cause trouble. git automatically created a local master and the remote master may have advanced, so git push would complain with an error. Currently the correct command would be "git push origin devel".

An alternative scenario is that you want to start work that will not be ready right away. So you start a topic branch

    git checkout -b topic origin/devel
    # work, commit, some time passes, work, commit
    git pull 	# integrate changes from devel
    # work, commit
    git pull
    git push 	# this one should push to origin/devel

In scenario three you planned to finish your work right away but the problem turned out to be harder. Here, the following would be nice

    git checkout -b devel origin/devel
    # work, commit, hmm... much harder ...
    git branch -m devel dolater
    # do something else
    git checkout dolater
    # finish work
    git pull    # integrate with other work on devel
    git push    # push back to shared branch

Another question is what to do with a local branch after you finished work. We recently had the "Re: best git practices, was Re: Git User's Survey 2007 unfinished summary continued" aka the 200-local-branches discussion.

There were different suggestions what to do. A reasonable suggestion was to delete the local branch after you're done. This clearly distinguishes between remote branches (which are mirrored as a remote tracking branch) and local branches. Local branches are _your_ branches while the remote branches contain the shared work. If you're done with your local work, delete your local branch. So maybe you should do

    git checkout origin/devel
    git branch -d devel

Now you're on a detached branch that points to origin/work. But how to do you get new changes from others? git pull would not work and git fetch neither.

Independently of what the best practice is, leaving the local work branch there shouldn't do any harm because I'm sure that some devs will forget to clean up, independently of what I tell them.

	Steffen
Previous: Junio C HamanoNext: Andreas Ericsson
Message 24 of 53 in “improve refspec handling in push”
  1. 0/10 improve refspec handling in pushSteffen Prohaska, Oct 28, 2007
  2. 01/10 push: change push to fail if short refname does not existSteffen Prohaska, Oct 28, 2007
  3. 02/10 push: teach push new flag --createSteffen Prohaska, Oct 28, 2007
  4. 03/10 push: support pushing HEAD to real branch nameSteffen Prohaska, Oct 28, 2007
  5. 04/10 push: add "git push HEAD" shorthand for 'push current branch to default repo'Steffen Prohaska, Oct 28, 2007
  6. 05/10 rename ref_matches_abbrev() to ref_abbrev_matches_full_with_fetch_rules()Steffen Prohaska, Oct 28, 2007
  7. 06/10 add ref_abbrev_matches_full_with_rev_parse_rules() comparing abbrev with full ref nameSteffen Prohaska, Oct 28, 2007
  8. 07/10 push: use same rules as git-rev-parse to resolve refspecsSteffen Prohaska, Oct 28, 2007
  9. 08/10 push: teach push to accept --verbose optionSteffen Prohaska, Oct 28, 2007
  10. 09/10 push: teach push to pass --verbose option to transport layerSteffen Prohaska, Oct 28, 2007
  11. 10/10 push: teach push to be quiet if local ref is strict subset of remote refSteffen Prohaska, Oct 28, 2007
  12. Junio C HamanoOct 30, 2007
  13. Steffen ProhaskaOct 30, 2007
  14. Andreas EricssonOct 30, 2007
  15. Steffen ProhaskaOct 30, 2007
  16. Junio C HamanoOct 30, 2007
  17. Steffen ProhaskaOct 31, 2007
  18. Junio C HamanoOct 31, 2007
  19. Junio C HamanoOct 31, 2007
  20. Steffen ProhaskaOct 31, 2007
  21. Junio C HamanoOct 31, 2007
  22. Steffen ProhaskaOct 31, 2007
  23. Junio C HamanoOct 31, 2007
  24. Steffen ProhaskaNov 1, 2007
  25. Andreas EricssonNov 1, 2007
  26. Steffen ProhaskaNov 1, 2007
  27. Junio C HamanoNov 1, 2007
  28. Steffen ProhaskaNov 2, 2007
  29. Junio C HamanoNov 2, 2007
  30. Steffen ProhaskaNov 2, 2007
  31. Junio C HamanoNov 2, 2007
  32. Steffen ProhaskaNov 2, 2007
  33. Andreas EricssonNov 2, 2007
  34. Tom PrinceNov 2, 2007
  35. Andreas EricssonNov 2, 2007
  36. Steffen ProhaskaNov 2, 2007
  37. Junio C HamanoNov 2, 2007
  38. Junio C HamanoNov 2, 2007
  39. Andreas EricssonNov 1, 2007
  40. Steffen ProhaskaNov 1, 2007
  41. Andreas EricssonNov 1, 2007
  42. Wincent ColaiutaNov 2, 2007
  43. Johannes SchindelinNov 2, 2007
  44. Steffen ProhaskaNov 2, 2007
  45. Wincent ColaiutaNov 2, 2007
  46. Daniel BarkalowOct 30, 2007
  47. Junio C HamanoOct 30, 2007
  48. Steffen ProhaskaOct 30, 2007
  49. Junio C HamanoOct 30, 2007
  50. Junio C HamanoOct 30, 2007
  51. Junio C HamanoOct 30, 2007
  52. Steffen ProhaskaOct 30, 2007
  53. Junio C HamanoOct 30, 2007

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.