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

Re: git push to a non-bare repository

From
Junio C Hamano <junkio@cox.net>
Date
Mar 20, 2007, 00:49 UTC
Message-ID
<7vodmod9id.fsf@assigned-by-dhcp.cox.net>
In-Reply-To
<45FF2393.6070700@vilain.net>
Sam Vilain <sam@vilain.net> writes:
Show 7 quoted lines
> Shawn O. Pearce wrote:
>> receive-pack isn't updating the HEAD reflog as its updating the
>> actual branch, not HEAD.  If you pushed instead to HEAD you should
>> see the HEAD reflog entry too.
>
> What about splitting HEAD when you push to the underlying branch, and
> making HEAD a non-symref?

I do not think any of the complication is needed, and I think somebody mentioned a good example, which is a firewalled host that can only be pushed into. In that example, even though he knows he could fetch in reverse direction in the ideal world, the network configuration does not let him do so, hence need for a push.

To deal with that sanely, people who push between non bare repositories can just forget about pushing into branch heads.

Instead, they can arrange their pushes to be a true mirror image of their fetch that they wish could do. To illustrate:

On repo A that can only be pushed into, if you _could_ fetch from repo B, you would:

	$ git fetch B
with something like this:
	[remote "B"] fetch = refs/heads/*:refs/remotes/B/*

But unfortunately because you can only push into A from B, you would run this on B instead:

	$ git push A
with:
	[remote "A"] push = refs/heads/*:refs/remotes/B/*

And after you perform your push, you come to the machine with repo A on it, and remembering that what you did was a mirror image of "git fetch B", you would:

	$ git merge remotes/B/master
and you are done.

In other words, don't think of refs/remotes/B as something that is for the use of "git fetch". Its purpose is to track the remote repository B's heads. You maintain that hierarchy by issuing fetch in repository A. You can issue push in repository B to do so as well.

I push into a live repository almost every day. My typical day concludes like this:

	gitster$ git push kernel-org-private
        gitster$ ssh kernel.org
        kernel.org$ git merge origin
        kernel.org$ Meta/Doit -pedantic &
        kernel.org$ exit
        ... go drink my tea ...
where
 (1) gitster is my private development machine
 (2) kernel.org is a machine made available to me by friendly
     k.org folks
 (3) Meta is a checkout of my 'todo' branch and 
 (4) Doit is a script to build all four public branches.

I always leave 'master' checked out on my kernel.org repository, and the push from my private machine is done with (I still use the non separate-remote layout):

	Push: refs/heads/master:refs/heads/origin
	Push: refs/heads/next:refs/heads/next
	Push: +refs/heads/pu:refs/heads/pu
	Push: refs/heads/maint:refs/heads/maint

So the first thing I do after logging in to kernel.org machine is to run "git merge origin" to bring the 'master' up-to-date. If you think of 'push' being mirror image of 'fetch' you would understand why. It is like issuing "git fetch" on kernel.org machine to retrive the hot-off-the-press from my private machine and then "git merge" it (usually "git pull" would do that as a single step).

However, sometimes I accidentally leave 'next' checked out. If I find out that I left non 'master' checked out, I would do "git reset --hard HEAD" before doing anything else, and I do not want my push to sometimes result in detached HEAD and sometimes not. I do not want to lose the information which branch I was on last (because the next thing I would do is on which branch Meta/Doit failed). If I _were_ annoyed enough by sometimes mistakenly pushing into the live branch, I would switch to separate remote layout and push into remotes/origin/* hierarchy, and there will be truly nothing to worry about after that point.

Previous: Sam VilainNext: Junio C Hamano
Message 19 of 27 in “git push to a non-bare repository”
  1. Matthieu MoyMar 18, 2007
  2. Junio C HamanoMar 18, 2007
  3. Sam VilainMar 18, 2007
  4. Jakub NarebskiMar 18, 2007
  5. Junio C HamanoMar 18, 2007
  6. Theodore TsoMar 19, 2007
  7. Junio C HamanoMar 19, 2007
  8. Shawn O. PearceMar 19, 2007
  9. Theodore TsoMar 19, 2007
  10. Shawn O. PearceMar 19, 2007
  11. Theodore TsoMar 19, 2007
  12. Shawn O. PearceMar 19, 2007
  13. Nicolas PitreMar 19, 2007
  14. Theodore TsoMar 19, 2007
  15. Junio C HamanoMar 19, 2007
  16. Nicolas PitreMar 19, 2007
  17. Nicolas PitreMar 19, 2007
  18. Sam VilainMar 19, 2007
  19. Junio C HamanoMar 20, 2007
  20. Junio C HamanoMar 20, 2007
  21. Theodore TsoMar 19, 2007
  22. Shawn O. PearceMar 19, 2007
  23. Junio C HamanoMar 19, 2007
  24. Matthieu MoyMar 19, 2007
  25. Jakub NarebskiMar 19, 2007
  26. Neil SchemenauerMar 21, 2007
  27. Sergio CallegariMar 19, 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.