* Wishlist for a bundle-only transport mode @ 2007-11-21 14:54 Santi Béjar 2007-11-21 15:04 ` Jakub Narebski ` (2 more replies) 0 siblings, 3 replies; 33+ messages in thread From: Santi Béjar @ 2007-11-21 14:54 UTC (permalink / raw) To: Git Mailing List Hi *, I have to work in a bundle-only mode, but there are some problems with it, namely: 1) git-clone does not accept a bundle file, even if git-fetch does. I've made a patch to use git-fetch in git-clone for this. 2) The bundles created with "git bundle" does not record the HEAD, they resolve the symbolic name to a branch name. 3) I can "git fetch" a bundle but I cannot "git push" a bundle, so if I have: [remote "bundle"] url = /file/to/bundle fetch = "+refs/heads/*:refs/remotes/bundle/*" $ git push bundle would create a bundle in /file/to/bundle with the same branches as a normal git push, but considering the remote branches as the local remotes/bundle/* Thank you Santi ^ permalink raw reply [flat|nested] 33+ messages in thread
* Re: Wishlist for a bundle-only transport mode 2007-11-21 14:54 Wishlist for a bundle-only transport mode Santi Béjar @ 2007-11-21 15:04 ` Jakub Narebski 2007-11-21 15:24 ` Santi Béjar 2007-11-21 15:46 ` Johannes Schindelin 2007-11-21 15:59 ` Johannes Schindelin 2007-11-21 17:06 ` Jakub Narebski 2 siblings, 2 replies; 33+ messages in thread From: Jakub Narebski @ 2007-11-21 15:04 UTC (permalink / raw) To: git Santi Béjar wrote: > 3) I can "git fetch" a bundle but I cannot "git push" a bundle, so if I have: > > [remote "bundle"] > url = /file/to/bundle > fetch = "+refs/heads/*:refs/remotes/bundle/*" > > $ git push bundle > > would create a bundle in /file/to/bundle with the same branches as a > normal git push, but considering the remote branches as the local > remotes/bundle/* And how you would differentiate between path meaning bundle, and path meaning "local" protocol, i.e. git repository on the same filesystem? "bundle = /file/to/bundle" perhaps... -- Jakub Narebski Warsaw, Poland ShadeHawk on #git ^ permalink raw reply [flat|nested] 33+ messages in thread
* Re: Wishlist for a bundle-only transport mode 2007-11-21 15:04 ` Jakub Narebski @ 2007-11-21 15:24 ` Santi Béjar 2007-11-21 15:46 ` Johannes Schindelin 1 sibling, 0 replies; 33+ messages in thread From: Santi Béjar @ 2007-11-21 15:24 UTC (permalink / raw) To: Jakub Narebski; +Cc: git On Nov 21, 2007 4:04 PM, Jakub Narebski <jnareb@gmail.com> wrote: > Santi Béjar wrote: > > > 3) I can "git fetch" a bundle but I cannot "git push" a bundle, so if I have: > > > > [remote "bundle"] > > url = /file/to/bundle > > fetch = "+refs/heads/*:refs/remotes/bundle/*" > > > > $ git push bundle > > > > would create a bundle in /file/to/bundle with the same branches as a > > normal git push, but considering the remote branches as the local > > remotes/bundle/* > > And how you would differentiate between path meaning bundle, and > path meaning "local" protocol, i.e. git repository on the same > filesystem? "bundle = /file/to/bundle" perhaps... Good point. The git repository must exist before pushing, but the bundle: 1) Exist and is a file, do nothing by default, maybe requiere a --overwrite 2) Does not exist, create the bundle, but maybe you've written badly the url, so the best thing would be to say explicitly that you wanted a bundle like you said. Santi ^ permalink raw reply [flat|nested] 33+ messages in thread
* Re: Wishlist for a bundle-only transport mode 2007-11-21 15:04 ` Jakub Narebski 2007-11-21 15:24 ` Santi Béjar @ 2007-11-21 15:46 ` Johannes Schindelin 2007-11-21 16:52 ` Jakub Narebski 1 sibling, 1 reply; 33+ messages in thread From: Johannes Schindelin @ 2007-11-21 15:46 UTC (permalink / raw) To: Jakub Narebski; +Cc: git, sbejar Hi, On Wed, 21 Nov 2007, Jakub Narebski wrote: > Santi B?jar wrote: > > > 3) I can "git fetch" a bundle but I cannot "git push" a bundle, so if I have: > > > > [remote "bundle"] > > ? url = /file/to/bundle > > ? fetch = "+refs/heads/*:refs/remotes/bundle/*" > > > > $ git push bundle > > > > would create a bundle in /file/to/bundle with the same branches as a > > normal git push, but considering the remote branches as the local > > remotes/bundle/* > > And how you would differentiate between path meaning bundle, and path > meaning "local" protocol, i.e. git repository on the same filesystem? Maybe because the git repository is specified as an existing directory? The bundle is specified as a (possibly non-existing) file... Hth, Dscho ^ permalink raw reply [flat|nested] 33+ messages in thread
* Re: Wishlist for a bundle-only transport mode 2007-11-21 15:46 ` Johannes Schindelin @ 2007-11-21 16:52 ` Jakub Narebski 2007-11-21 16:59 ` Johannes Schindelin 0 siblings, 1 reply; 33+ messages in thread From: Jakub Narebski @ 2007-11-21 16:52 UTC (permalink / raw) To: Johannes Schindelin, Santi Béjar; +Cc: git Johannes Schindelin wrote: > On Wed, 21 Nov 2007, Jakub Narebski wrote: >> Santi Bejar wrote: >> >>> 3) I can "git fetch" a bundle but I cannot "git push" a bundle, so if I have: >>> >>> [remote "bundle"] >>> url = /file/to/bundle >>> fetch = "+refs/heads/*:refs/remotes/bundle/*" >>> >>> $ git push bundle >>> >>> would create a bundle in /file/to/bundle with the same branches as a >>> normal git push, but considering the remote branches as the local >>> remotes/bundle/* >> >> And how you would differentiate between path meaning bundle, and path >> meaning "local" protocol, i.e. git repository on the same filesystem? > > Maybe because the git repository is specified as an existing directory? > The bundle is specified as a (possibly non-existing) file... That has the disadvantage of pushing to bundle when you make an error in the lastpart of path to existing repository. After thinking about it a bit, I think it would be better to use bundle:// pseudoprotocol for the URL including config (bundle://file, bundle:///path/to/bundle) and --bundle option to git push for commandline. -- Jakub Narebski Poland ^ permalink raw reply [flat|nested] 33+ messages in thread
* Re: Wishlist for a bundle-only transport mode 2007-11-21 16:52 ` Jakub Narebski @ 2007-11-21 16:59 ` Johannes Schindelin 2007-11-21 17:11 ` Jakub Narebski 0 siblings, 1 reply; 33+ messages in thread From: Johannes Schindelin @ 2007-11-21 16:59 UTC (permalink / raw) To: Jakub Narebski; +Cc: Santi Béjar, git Hi, On Wed, 21 Nov 2007, Jakub Narebski wrote: > Johannes Schindelin wrote: > > On Wed, 21 Nov 2007, Jakub Narebski wrote: > >> Santi Bejar wrote: > >> > >>> 3) I can "git fetch" a bundle but I cannot "git push" a bundle, so if I have: > >>> > >>> [remote "bundle"] > >>> url = /file/to/bundle > >>> fetch = "+refs/heads/*:refs/remotes/bundle/*" > >>> > >>> $ git push bundle > >>> > >>> would create a bundle in /file/to/bundle with the same branches as a > >>> normal git push, but considering the remote branches as the local > >>> remotes/bundle/* > >> > >> And how you would differentiate between path meaning bundle, and path > >> meaning "local" protocol, i.e. git repository on the same filesystem? > > > > Maybe because the git repository is specified as an existing directory? > > The bundle is specified as a (possibly non-existing) file... > > That has the disadvantage of pushing to bundle when you make an error > in the lastpart of path to existing repository. As I wrote in another reply, I would not allow overwriting an existing file. > After thinking about it a bit, I think it would be better to use > bundle:// pseudoprotocol for the URL including config (bundle://file, > bundle:///path/to/bundle) and --bundle option to git push for > commandline. I don't like that at all. Specifying a non-existing file should be good enough. Ciao, Dscho ^ permalink raw reply [flat|nested] 33+ messages in thread
* Re: Wishlist for a bundle-only transport mode 2007-11-21 16:59 ` Johannes Schindelin @ 2007-11-21 17:11 ` Jakub Narebski 2007-11-21 17:26 ` Johannes Schindelin 0 siblings, 1 reply; 33+ messages in thread From: Jakub Narebski @ 2007-11-21 17:11 UTC (permalink / raw) To: Johannes Schindelin; +Cc: Santi Béjar, git Johannes Schindelin wrote: > On Wed, 21 Nov 2007, Jakub Narebski wrote: >> Johannes Schindelin wrote: >>> On Wed, 21 Nov 2007, Jakub Narebski wrote: >>>> Santi Bejar wrote: >>>> >>>>> 3) I can "git fetch" a bundle but I cannot "git push" a bundle, so if I have: >>>>> >>>>> [remote "bundle"] >>>>> url = /file/to/bundle >>>>> fetch = "+refs/heads/*:refs/remotes/bundle/*" >>>>> >>>>> $ git push bundle >>>>> >>>>> would create a bundle in /file/to/bundle with the same branches as a >>>>> normal git push, but considering the remote branches as the local >>>>> remotes/bundle/* >>>> >>>> And how you would differentiate between path meaning bundle, and path >>>> meaning "local" protocol, i.e. git repository on the same filesystem? >>> >>> Maybe because the git repository is specified as an existing directory? >>> The bundle is specified as a (possibly non-existing) file... >> >> That has the disadvantage of pushing to bundle when you make an error >> in the lastpart of path to existing repository. > > As I wrote in another reply, I would not allow overwriting an existing > file. > Specifying a non-existing file should be good enough. What I meant here that if you do "git push /some/path/to/rpeo.git", with mistake in the last part of path to repository, you would end up with a bundle, and you would have to really watch what happened to catch the error. I'd rather use "git push bundle:///some/path/to/bundle" or "git push --bundle bundlename" to catch errors better. Besides it should be IMHO be possible to overwrite bundle if you are doing fast-forward push... -- Jakub Narebski Poland ^ permalink raw reply [flat|nested] 33+ messages in thread
* Re: Wishlist for a bundle-only transport mode 2007-11-21 17:11 ` Jakub Narebski @ 2007-11-21 17:26 ` Johannes Schindelin 2007-11-21 17:52 ` Jakub Narebski 2007-11-22 9:42 ` Santi Béjar 0 siblings, 2 replies; 33+ messages in thread From: Johannes Schindelin @ 2007-11-21 17:26 UTC (permalink / raw) To: Jakub Narebski; +Cc: Santi Béjar, git Hi, On Wed, 21 Nov 2007, Jakub Narebski wrote: > Johannes Schindelin wrote: > > On Wed, 21 Nov 2007, Jakub Narebski wrote: > > > >> That has the disadvantage of pushing to bundle when you make an error > >> in the lastpart of path to existing repository. > > > > As I wrote in another reply, I would not allow overwriting an existing > > file. > > > Specifying a non-existing file should be good enough. > > What I meant here that if you do "git push /some/path/to/rpeo.git", with > mistake in the last part of path to repository, you would end up with a > bundle, and you would have to really watch what happened to catch the > error. I use tab completion all the time, so this would not happen to me. IMHO that is a lesser issue than to introduce a "protocol". > I'd rather use "git push bundle:///some/path/to/bundle" or "git push > --bundle bundlename" to catch errors better. > > Besides it should be IMHO be possible to overwrite bundle if you are > doing fast-forward push... Not as far as I can see. A push there would see what the bundle has already, and put them into the new bundle as _prerequisites_. So the bundle would lose information. BTW this was my gripe (that I decided not to make public earlier) with Santi's proposal to begin with: a push would not have any way to specify what the other side has already. So I think "git push <bundle>" is the wrong way of creating a bundle. Except if we add some cunning strategy not to overwrite, ever, but to create <bundle>.<n> with an incrementing <n>. But that might be too much. Ciao, Dscho ^ permalink raw reply [flat|nested] 33+ messages in thread
* Re: Wishlist for a bundle-only transport mode 2007-11-21 17:26 ` Johannes Schindelin @ 2007-11-21 17:52 ` Jakub Narebski 2007-11-22 9:42 ` Santi Béjar 1 sibling, 0 replies; 33+ messages in thread From: Jakub Narebski @ 2007-11-21 17:52 UTC (permalink / raw) To: Johannes Schindelin; +Cc: Santi Béjar, git On Wed, 21 Nov 2007, Johannes Schindelin wrote: > On Wed, 21 Nov 2007, Jakub Narebski wrote: >> Johannes Schindelin wrote: >>> On Wed, 21 Nov 2007, Jakub Narebski wrote: >>> >>>> That has the disadvantage of pushing to bundle when you make an error >>>> in the lastpart of path to existing repository. >>> >>> As I wrote in another reply, I would not allow overwriting an existing >>> file. >> >>> Specifying a non-existing file should be good enough. >> >> What I meant here that if you do "git push /some/path/to/rpeo.git", with >> mistake in the last part of path to repository, you would end up with a >> bundle, and you would have to really watch what happened to catch the >> error. > > I use tab completion all the time, so this would not happen to me. IMHO > that is a lesser issue than to introduce a "protocol". When I copy'n'paste pathname I sometimes catch return / linefeed in the middle, ending with incorect pathname (which would create bundle). Tab completon is not always solution (tab completion can be slow, or nonexistent). [cut] But I agree that because "git create bundle" needs refspecs _and revlist_, while "git push" gets only refspecs because it calculates revlist it would be better to have to use "git bundle create" to create bundle. Contrary to "git clone <bundle>" which should just work IMHO. -- Jakub Narebski Poland ^ permalink raw reply [flat|nested] 33+ messages in thread
* Re: Wishlist for a bundle-only transport mode 2007-11-21 17:26 ` Johannes Schindelin 2007-11-21 17:52 ` Jakub Narebski @ 2007-11-22 9:42 ` Santi Béjar 2007-11-22 10:02 ` Junio C Hamano 1 sibling, 1 reply; 33+ messages in thread From: Santi Béjar @ 2007-11-22 9:42 UTC (permalink / raw) To: Johannes Schindelin; +Cc: Jakub Narebski, git On Nov 21, 2007 6:26 PM, Johannes Schindelin <Johannes.Schindelin@gmx.de> wrote: > Hi, > > On Wed, 21 Nov 2007, Jakub Narebski wrote: > > > Johannes Schindelin wrote: > > > On Wed, 21 Nov 2007, Jakub Narebski wrote: > > > > > >> That has the disadvantage of pushing to bundle when you make an error > > >> in the lastpart of path to existing repository. > > > > > > As I wrote in another reply, I would not allow overwriting an existing > > > file. > > > > > Specifying a non-existing file should be good enough. > > > > What I meant here that if you do "git push /some/path/to/rpeo.git", with > > mistake in the last part of path to repository, you would end up with a > > bundle, and you would have to really watch what happened to catch the > > error. > > I use tab completion all the time, so this would not happen to me. IMHO > that is a lesser issue than to introduce a "protocol". > > > I'd rather use "git push bundle:///some/path/to/bundle" or "git push > > --bundle bundlename" to catch errors better. I would vote for the later, and a way to configure this in the config. > > > > Besides it should be IMHO be possible to overwrite bundle if you are > > doing fast-forward push... > > Not as far as I can see. A push there would see what the bundle has > already, and put them into the new bundle as _prerequisites_. So the > bundle would lose information. I prefer not to overwrite an existing bundle. > > BTW this was my gripe (that I decided not to make public earlier) with > Santi's proposal to begin with: a push would not have any way to specify > what the other side has already. So I think "git push <bundle>" is the > wrong way of creating a bundle. Sorry but I do not understand this. I think this two lines could be equivalent: git push --bundle bundle.bdl "refs/heads/master:refs/remotes/bundle/master" git bundle create bundle.bdl refs/heads/master ^refs/remotes/bundle/master > > Except if we add some cunning strategy not to overwrite, ever, but to > create <bundle>.<n> with an incrementing <n>. But that might be too much. That make sense. Santi ^ permalink raw reply [flat|nested] 33+ messages in thread
* Re: Wishlist for a bundle-only transport mode 2007-11-22 9:42 ` Santi Béjar @ 2007-11-22 10:02 ` Junio C Hamano 2007-11-23 9:18 ` Jakub Narebski 0 siblings, 1 reply; 33+ messages in thread From: Junio C Hamano @ 2007-11-22 10:02 UTC (permalink / raw) To: Santi Béjar; +Cc: Johannes Schindelin, Jakub Narebski, git "Santi Béjar" <sbejar@gmail.com> writes: > Sorry but I do not understand this. I think this two lines could be equivalent: > > git push --bundle bundle.bdl "refs/heads/master:refs/remotes/bundle/master" > git bundle create bundle.bdl refs/heads/master ^refs/remotes/bundle/master Interesting. $ git push $something ours:theirs has defined semantics for any value of $something. * give $something objects it lacks, so that the object $ours become complete in there; * set the ref in $theirs to point at the object $ours. So "git push bundle.bdl refspec" should: * First read bundle.bdl, to find out what objects it gives to the recipients; * Add missing objects to it to make it up to date wrt "ours", iow, fetching from the updated bundle would now give "ours"; * Record the object "ours" as "theirs" ref, iow, listing the updated bundle would show "theis" ref pointing at that object. If bundle.bdl does not exist yet, it is like pushing into a freshly initialized empty repository. ^ permalink raw reply [flat|nested] 33+ messages in thread
* Re: Wishlist for a bundle-only transport mode 2007-11-22 10:02 ` Junio C Hamano @ 2007-11-23 9:18 ` Jakub Narebski 2007-11-23 9:31 ` Junio C Hamano 0 siblings, 1 reply; 33+ messages in thread From: Jakub Narebski @ 2007-11-23 9:18 UTC (permalink / raw) To: Junio C Hamano; +Cc: Santi Béjar, Johannes Schindelin, git On Thu, 22 Nov 2007, Junio C Hamano : > "Santi Béjar" <sbejar@gmail.com> writes: > >> Sorry but I do not understand this. I think this two lines could be equivalent: >> >> git push --bundle bundle.bdl "refs/heads/master:refs/remotes/bundle/master" >> git bundle create bundle.bdl refs/heads/master ^refs/remotes/bundle/master > > Interesting. > > $ git push $something ours:theirs > > has defined semantics for any value of $something. > > * give $something objects it lacks, so that the object $ours > become complete in there; > > * set the ref in $theirs to point at the object $ours. > > So "git push bundle.bdl refspec" should: > > * First read bundle.bdl, to find out what objects it gives to > the recipients; > > * Add missing objects to it to make it up to date wrt "ours", > iow, fetching from the updated bundle would now give "ours"; > > * Record the object "ours" as "theirs" ref, iow, listing > the updated bundle would show "theirs" ref pointing at that > object. > > If bundle.bdl does not exist yet, it is like pushing into a > freshly initialized empty repository. But for that I think "git bundle" should learn new subcommand: "git bundle update", which would use refs existing in given bundle as prerequisites, and either update bundle (create anew or just concatenate next pack) or create incremental bundle. Something similar to incremental mode or update command of archivers... -- Jakub Narebski Poland ^ permalink raw reply [flat|nested] 33+ messages in thread
* Re: Wishlist for a bundle-only transport mode 2007-11-23 9:18 ` Jakub Narebski @ 2007-11-23 9:31 ` Junio C Hamano 2007-11-23 10:04 ` Jakub Narebski 2007-11-23 10:13 ` Santi Béjar 0 siblings, 2 replies; 33+ messages in thread From: Junio C Hamano @ 2007-11-23 9:31 UTC (permalink / raw) To: Jakub Narebski; +Cc: Santi Béjar, Johannes Schindelin, git Jakub Narebski <jnareb@gmail.com> writes: > On Thu, 22 Nov 2007, Junio C Hamano : >> "Santi Béjar" <sbejar@gmail.com> writes: >> >>> Sorry but I do not understand this. I think this two lines could be equivalent: >>> >>> git push --bundle bundle.bdl "refs/heads/master:refs/remotes/bundle/master" >>> git bundle create bundle.bdl refs/heads/master ^refs/remotes/bundle/master >> >> Interesting. >> >> $ git push $something ours:theirs >> >> has defined semantics for any value of $something. >> ... >> If bundle.bdl does not exist yet, it is like pushing into a >> freshly initialized empty repository. > > But for that I think "git bundle" should learn new subcommand: > "git bundle update", which would use refs existing in given > bundle as prerequisites, and either update bundle (create anew > or just concatenate next pack) or create incremental bundle. > > Something similar to incremental mode or update command of > archivers... I was disagreeing with Santi's "'push --bundle' and 'bundle create' can be equivalent". They can't be, as "push" is always "update" and never "create". So I do not quite get your "But for that I think"; I think you are just agreeing with me. Even if we taught "push" to create (which I doubt would happen due to its security and administrative implications), it would not make the two any closer to being equivalent. For them to become equivalent, we would need to have "push" unlearn how to update, which would never happen ;-). ^ permalink raw reply [flat|nested] 33+ messages in thread
* Re: Wishlist for a bundle-only transport mode 2007-11-23 9:31 ` Junio C Hamano @ 2007-11-23 10:04 ` Jakub Narebski 2007-11-23 10:13 ` Santi Béjar 1 sibling, 0 replies; 33+ messages in thread From: Jakub Narebski @ 2007-11-23 10:04 UTC (permalink / raw) To: Junio C Hamano; +Cc: Santi Béjar, Johannes Schindelin, git On Fri, 23 Nov 2007, Junio C Hamano wrote: > Jakub Narebski <jnareb@gmail.com> writes: >> On Thu, 22 Nov 2007, Junio C Hamano : >>> "Santi Béjar" <sbejar@gmail.com> writes: >>> >>>> Sorry but I do not understand this. I think this two lines could be equivalent: >>>> >>>> git push --bundle bundle.bdl "refs/heads/master:refs/remotes/bundle/master" >>>> git bundle create bundle.bdl refs/heads/master ^refs/remotes/bundle/master >>> >>> Interesting. >>> >>> $ git push $something ours:theirs >>> >>> has defined semantics for any value of $something. >>> ... >>> If bundle.bdl does not exist yet, it is like pushing into a >>> freshly initialized empty repository. >> >> But for that I think "git bundle" should learn new subcommand: >> "git bundle update", which would use refs existing in given >> bundle as prerequisites, and either update bundle (create anew >> or just concatenate next pack) or create incremental bundle. >> >> Something similar to incremental mode or update command of >> archivers... > > I was disagreeing with Santi's "'push --bundle' and 'bundle > create' can be equivalent". They can't be, as "push" is always > "update" and never "create". So I do not quite get your "But for > that I think"; I think you are just agreeing with me. Bad choice of words on my part... and I didn't parse that you were disagreeing as well as commenting. :-/ > Even if we taught "push" to create (which I doubt would happen > due to its security and administrative implications), it would > not make the two any closer to being equivalent. For them to > become equivalent, we would need to have "push" unlearn how to > update, which would never happen ;-). I also think that pushing to bundle might be not a good idea; but I think that "git clone <bundle>" should just work. Nevertheless I think that having "git bundle update" or "git bundle create --reference=<old bundle>" (or both) would be a good thing, as it would free us from remembering or tagging when last bundle was created. Could anyone who uses "git bundle" actively raise a voice? -- Jakub Narebski Poland ^ permalink raw reply [flat|nested] 33+ messages in thread
* Re: Wishlist for a bundle-only transport mode 2007-11-23 9:31 ` Junio C Hamano 2007-11-23 10:04 ` Jakub Narebski @ 2007-11-23 10:13 ` Santi Béjar 2007-11-23 12:18 ` Johannes Schindelin 2007-11-23 15:06 ` Junio C Hamano 1 sibling, 2 replies; 33+ messages in thread From: Santi Béjar @ 2007-11-23 10:13 UTC (permalink / raw) To: Junio C Hamano; +Cc: Jakub Narebski, Johannes Schindelin, git On Nov 23, 2007 10:31 AM, Junio C Hamano <gitster@pobox.com> wrote: > > I was disagreeing with Santi's "'push --bundle' and 'bundle > create' can be equivalent". They can't be, as "push" is always > "update" and never "create". So I do not quite get your "But for > that I think"; I think you are just agreeing with me. > > Even if we taught "push" to create (which I doubt would happen > due to its security and administrative implications), it would > not make the two any closer to being equivalent. For them to > become equivalent, we would need to have "push" unlearn how to > update, which would never happen ;-). > OK. So git push will never understand bundles. My motivation was to have a similar workflow with bundles as with pushes, or at least as similar as possible. So another possible workflow would be with a: git bundle push [<bundle> [<refspec>]] that creates a bundle # Have a project with different branches (master, next, pu) $ git bundle push bundle.bdl # would create a complete bundle.bdl with all the local branches (with HEAD) # You send it to the other person and he does: $ git clone bundle.bdl project $ cat .git/config ... [remote "origin"] url = /path/to/bundle.bdl fetch = +refs/heads/*:refs/remotes/origin/* # He makes changes, commits and so on and then he wants to send to back a bundle $ git bundle push [<remote>] # This creates an incremental bundle with the local branches (with HEAD) as specified # by remote.<remote>.* (possibly with an implicit "push" line "refs/heads/*:refs/heads/*" # And considering the remotes/origin/* as the bases for the bundle # Then I got it and do a: $ git remote add bundle /path/to/bundle $ git fetch # Now maybe I just want to send him the master branch $ git bundle push origin master:master # If I want to send him a complete bundle $ git bundle push The important part, for me, is to keep remote tracking branches to know the bases for the next bundle. It does not matter if it is "git push", "git bundle push", "git push --bundle", "git bundle update", ... Santi ^ permalink raw reply [flat|nested] 33+ messages in thread
* Re: Wishlist for a bundle-only transport mode 2007-11-23 10:13 ` Santi Béjar @ 2007-11-23 12:18 ` Johannes Schindelin 2007-11-23 15:06 ` Junio C Hamano 1 sibling, 0 replies; 33+ messages in thread From: Johannes Schindelin @ 2007-11-23 12:18 UTC (permalink / raw) To: Santi Béjar; +Cc: Junio C Hamano, Jakub Narebski, git Hi, On Fri, 23 Nov 2007, Santi B?jar wrote: > My motivation was to have a similar workflow with bundles as with > pushes, or at least as similar as possible. So another possible workflow > would be with a: > > git bundle push [<bundle> [<refspec>]] > > that creates a bundle What about git bundle create retort.bundle --all \ --not $(git ls-remote the-other.bundle | cut -c1-40) Hmm? If you need that quite often, it should not be hard at all for you to add an option to the "create" named "--haves-from=<bundle>". But I'd rather script it. Ciao, Dscho ^ permalink raw reply [flat|nested] 33+ messages in thread
* Re: Wishlist for a bundle-only transport mode 2007-11-23 10:13 ` Santi Béjar 2007-11-23 12:18 ` Johannes Schindelin @ 2007-11-23 15:06 ` Junio C Hamano 2007-11-23 15:34 ` Santi Béjar 1 sibling, 1 reply; 33+ messages in thread From: Junio C Hamano @ 2007-11-23 15:06 UTC (permalink / raw) To: Santi Béjar; +Cc: Junio C Hamano, Jakub Narebski, Johannes Schindelin, git "Santi Béjar" <sbejar@gmail.com> writes: > OK. So git push will never understand bundles. Why not? Because you will not code it? I am not opposed to the notion of "pushing to a bundle to update it." I am just saying that "pushing to create" only for bundle and not regular repository is very inconsistent. ^ permalink raw reply [flat|nested] 33+ messages in thread
* Re: Wishlist for a bundle-only transport mode 2007-11-23 15:06 ` Junio C Hamano @ 2007-11-23 15:34 ` Santi Béjar 2007-11-23 16:05 ` Junio C Hamano 2007-11-23 19:09 ` Jakub Narebski 0 siblings, 2 replies; 33+ messages in thread From: Santi Béjar @ 2007-11-23 15:34 UTC (permalink / raw) To: Junio C Hamano; +Cc: Jakub Narebski, Johannes Schindelin, git On Nov 23, 2007 4:06 PM, Junio C Hamano <gitster@pobox.com> wrote: > "Santi Béjar" <sbejar@gmail.com> writes: > > > OK. So git push will never understand bundles. > > Why not? Sorry, I misunderstood you, because pushing to an existing bundle loses information, and that is also inconsistent with pushing to regular repositories. > Because you will not code it? > > I am not opposed to the notion of "pushing to a bundle to > update it." I am just saying that "pushing to create" only for > bundle and not regular repository is very inconsistent. Santi ^ permalink raw reply [flat|nested] 33+ messages in thread
* Re: Wishlist for a bundle-only transport mode 2007-11-23 15:34 ` Santi Béjar @ 2007-11-23 16:05 ` Junio C Hamano 2007-11-23 16:39 ` Santi Béjar 2007-11-23 19:09 ` Jakub Narebski 1 sibling, 1 reply; 33+ messages in thread From: Junio C Hamano @ 2007-11-23 16:05 UTC (permalink / raw) To: Santi Béjar; +Cc: Junio C Hamano, Jakub Narebski, Johannes Schindelin, git "Santi Béjar" <sbejar@gmail.com> writes: >> > OK. So git push will never understand bundles. >> >> Why not? > > Sorry, I misunderstood you, because pushing to an existing > bundle loses information, and that is also inconsistent with pushing > to regular repositories. Maybe I am missing something from the discussion, but what information loss are you referring to? ^ permalink raw reply [flat|nested] 33+ messages in thread
* Re: Wishlist for a bundle-only transport mode 2007-11-23 16:05 ` Junio C Hamano @ 2007-11-23 16:39 ` Santi Béjar 2007-11-24 19:15 ` Junio C Hamano 0 siblings, 1 reply; 33+ messages in thread From: Santi Béjar @ 2007-11-23 16:39 UTC (permalink / raw) To: Junio C Hamano; +Cc: Jakub Narebski, Johannes Schindelin, git On Nov 23, 2007 5:05 PM, Junio C Hamano <gitster@pobox.com> wrote: > "Santi Béjar" <sbejar@gmail.com> writes: > > >> > OK. So git push will never understand bundles. > >> > >> Why not? > > > > Sorry, I misunderstood you, because pushing to an existing > > bundle loses information, and that is also inconsistent with pushing > > to regular repositories. > > Maybe I am missing something from the discussion, but what > information loss are you referring to? > Because you create an incremental bundle, so all the objects in the old bundle will not be in the new bundle. But it can be considered the natural behavior of bundles. But anyway, pushing to an existing bundle is not very convenient (at leas for me) because it forces you to keep the bundles. I think the most convenient way would be to have remote tracking branching to record the bases for future bundles. For now, I will do an script that behaves like the "git bundle push" that I described and then I'll report the pro/cons that it has. Thank you all for the discussion, it was very fruitful. Santi P.D.: Am I the only one doing a bundle-only transport mode? If not, can you comment on the different suggestions that have been said. Thanks a lot. ^ permalink raw reply [flat|nested] 33+ messages in thread
* Re: Wishlist for a bundle-only transport mode 2007-11-23 16:39 ` Santi Béjar @ 2007-11-24 19:15 ` Junio C Hamano 0 siblings, 0 replies; 33+ messages in thread From: Junio C Hamano @ 2007-11-24 19:15 UTC (permalink / raw) To: Santi Béjar; +Cc: Jakub Narebski, Johannes Schindelin, git "Santi Béjar" <sbejar@gmail.com> writes: > On Nov 23, 2007 5:05 PM, Junio C Hamano <gitster@pobox.com> wrote: > ... >> Maybe I am missing something from the discussion, but what >> information loss are you referring to? > > Because you create an incremental bundle, so all the objects in the > old bundle will > not be in the new bundle. But it can be considered the natural > behavior of bundles. It might be natural if you are thinking within the limit of "git bundle create", but it is not natural for "git push" at all. I think treating a bundle as if it is a bare repository with a funny representation wouldn't be so wrong, at least from the user interface point of view. IOW, I think it is natural for these: $ git push $remote $refspec $ git fetch $remote $refspec to work as "expected" when $remote is actually a local file that is a bundle, and in fact, "git fetch" should already work that way. What's "expected" for a push? You push from your repository the objects needed to complete LHS of given $refspec into the $remote, and then update the refs in the $remote specified by the $refspec. There is no deletion of existing objects from the $remote. That is what's expected for a push. So if you want to implement "pushing into a bundle", the implementation would be: * Find the required objects in the existing bundle. If the bundle file does not exist, it might be natural to treat it as if you are pushing into an empty but initialized regular repository. If we choose to do this, for a nonexistent bundle file, the set of required objects is an empty set. * Find the recorded heads in the existing bundle. Add or replace them with the RHS of $refspecs being pushed to come up with the new set of heads for the updated bundle. We would want to perform the ordinary "fast-forward" safety and reject a push as needed. * If there are HEADs in the updated bundle that the pushing repository does not have, fetch them (and their required objects) first, as it is necessary for the next step. * Run this pipeline in the pushing repository to generate a packdata stream: $ git rev-list --objects <heads in the updated bundle> \ --not <required objects in the bundle> | git pack-objects --stdout This packdata stream will be the payload of the updated bundle. * The updated bundle will require the same set of objects as the bundle before the update. This is quite different from the way how the other "transports" are implemented internally to push into usual repositories, but that is perfectly fine. What the end user sees will be consistent if you implement "push into bundle" that way and that is what matters. Note. I am not saying that we _should_ allow pushing into a bundle to update. I am just saying that if we were to implement "git push" into a bundle, that should behave as close as other push transports from the end uesr's point of view. If you want different "object losing" semantics, "git bundle create" to create a new bundle is already there for you. You just shouldn't overload that different semantics to "git push", because that would confuse users without much gain. ^ permalink raw reply [flat|nested] 33+ messages in thread
* Re: Wishlist for a bundle-only transport mode 2007-11-23 15:34 ` Santi Béjar 2007-11-23 16:05 ` Junio C Hamano @ 2007-11-23 19:09 ` Jakub Narebski 1 sibling, 0 replies; 33+ messages in thread From: Jakub Narebski @ 2007-11-23 19:09 UTC (permalink / raw) To: Santi Béjar; +Cc: Junio C Hamano, Johannes Schindelin, git On Fri, 23 Nov 2007, Santi Béjar wrote: > On Nov 23, 2007 4:06 PM, Junio C Hamano <gitster@pobox.com> wrote: >> "Santi Béjar" <sbejar@gmail.com> writes: >> >>> OK. So git push will never understand bundles. >> >> Why not? > > Sorry, I misunderstood you, because pushing to an existing > bundle loses information, and that is also inconsistent with pushing > to regular repositories. Pushing to regular repositories _adds_ information (adds objects and advances refs). Junio proposed that "git push <bundle>" do the same, which means getting refs from bundle, and adding objects to bundle creating new bundle, which contain all the old one has, and all what was created since then. What information would be lost? Johannes provided alternate solution which you can use even now, namely how to create "incremental" bundle, which has all objects since last bundle was created. But this does not play with the way push works with ordinary, regular repositories. P.S. Code speaks louder than words ;-) -- Jakub Narebski Poland ^ permalink raw reply [flat|nested] 33+ messages in thread
* Re: Wishlist for a bundle-only transport mode 2007-11-21 14:54 Wishlist for a bundle-only transport mode Santi Béjar 2007-11-21 15:04 ` Jakub Narebski @ 2007-11-21 15:59 ` Johannes Schindelin 2007-11-21 16:15 ` Santi Béjar 2007-11-21 16:23 ` Wishlist for a bundle-only transport mode Kristian Høgsberg 2007-11-21 17:06 ` Jakub Narebski 2 siblings, 2 replies; 33+ messages in thread From: Johannes Schindelin @ 2007-11-21 15:59 UTC (permalink / raw) To: Santi Béjar; +Cc: Git Mailing List Hi, On Wed, 21 Nov 2007, Santi B?jar wrote: > 1) git-clone does not accept a bundle file, even if git-fetch does. I've > made a patch to use git-fetch in git-clone for this. This, along with rewriting git-clone as a very thin wrapper over git-init, -remote and -fetch, is a really low hanging fruit. Or maybe go the full nine yards and build it in. Should be a breeze now, given parse_options() and run_command(). > 2) The bundles created with "git bundle" does not record the HEAD, they > resolve the symbolic name to a branch name. It imitates ls-remote output. > 3) I can "git fetch" a bundle but I cannot "git push" a bundle, so if I have: > > [remote "bundle"] > url = /file/to/bundle > fetch = "+refs/heads/*:refs/remotes/bundle/*" > > $ git push bundle > > would create a bundle in /file/to/bundle with the same branches as a > normal git push, but considering the remote branches as the local > remotes/bundle/* Does not seem to be too complicated to add it to transport.c IMHO. Something similar to rsync_transport_push(). And I'd definitely refuse to overwrite any existing file. Ciao, Dscho ^ permalink raw reply [flat|nested] 33+ messages in thread
* Re: Wishlist for a bundle-only transport mode 2007-11-21 15:59 ` Johannes Schindelin @ 2007-11-21 16:15 ` Santi Béjar 2007-11-21 16:36 ` Johannes Schindelin 2007-11-21 16:53 ` [PATCH] bundle create: keep symbolic refs' names instead of resolving them Johannes Schindelin 2007-11-21 16:23 ` Wishlist for a bundle-only transport mode Kristian Høgsberg 1 sibling, 2 replies; 33+ messages in thread From: Santi Béjar @ 2007-11-21 16:15 UTC (permalink / raw) To: Johannes Schindelin; +Cc: Git Mailing List On Nov 21, 2007 4:59 PM, Johannes Schindelin <Johannes.Schindelin@gmx.de> wrote: > Hi, > > On Wed, 21 Nov 2007, Santi B?jar wrote: > > > 1) git-clone does not accept a bundle file, even if git-fetch does. I've > > made a patch to use git-fetch in git-clone for this. > > This, along with rewriting git-clone as a very thin wrapper over git-init, > -remote and -fetch, is a really low hanging fruit. For the basic/normal mode it can be a very thin wrapper but you have to support --local, --shared, --reference... > > 2) The bundles created with "git bundle" does not record the HEAD, they > > resolve the symbolic name to a branch name. > > It imitates ls-remote output. No, it does not. With a newly created project with one commit: $ git ls-remote git.git b71992713c17c3a29f9566e1b50e8cf402375faf HEAD b71992713c17c3a29f9566e1b50e8cf402375faf refs/heads/master $ git bundle create git.bdl HEAD master $ git bundle list-heads git.bdl b71992713c17c3a29f9566e1b50e8cf402375faf refs/heads/master b71992713c17c3a29f9566e1b50e8cf402375faf refs/heads/master Santi ^ permalink raw reply [flat|nested] 33+ messages in thread
* Re: Wishlist for a bundle-only transport mode 2007-11-21 16:15 ` Santi Béjar @ 2007-11-21 16:36 ` Johannes Schindelin 2007-11-21 16:44 ` Santi Béjar 2007-11-21 16:53 ` [PATCH] bundle create: keep symbolic refs' names instead of resolving them Johannes Schindelin 1 sibling, 1 reply; 33+ messages in thread From: Johannes Schindelin @ 2007-11-21 16:36 UTC (permalink / raw) To: Santi Béjar; +Cc: Git Mailing List Hi, On Wed, 21 Nov 2007, Santi B?jar wrote: > On Nov 21, 2007 4:59 PM, Johannes Schindelin <Johannes.Schindelin@gmx.de> wrote: > > > On Wed, 21 Nov 2007, Santi B?jar wrote: > > > > > 1) git-clone does not accept a bundle file, even if git-fetch does. > > > I've made a patch to use git-fetch in git-clone for this. > > > > This, along with rewriting git-clone as a very thin wrapper over > > git-init, -remote and -fetch, is a really low hanging fruit. > > For the basic/normal mode it can be a very thin wrapper but you have to > support --local, --shared, --reference... That is not all that difficult. > > > 2) The bundles created with "git bundle" does not record the HEAD, > > > they resolve the symbolic name to a branch name. > > > > It imitates ls-remote output. > > No, it does not. > > With a newly created project with one commit: > > $ git ls-remote git.git > b71992713c17c3a29f9566e1b50e8cf402375faf HEAD > b71992713c17c3a29f9566e1b50e8cf402375faf refs/heads/master > > $ git bundle create git.bdl HEAD master > > $ git bundle list-heads git.bdl > b71992713c17c3a29f9566e1b50e8cf402375faf refs/heads/master > b71992713c17c3a29f9566e1b50e8cf402375faf refs/heads/master Ah, I misunderstood. I thought you were expecting that the first line would read refs/heads/master HEAD Alas, this behaviour stems from dwim_ref() returning "refs/heads/master" as real ref. I am not quite sure how to solve this, though. Let me see what I can come up with. Ciao, Dscho ^ permalink raw reply [flat|nested] 33+ messages in thread
* Re: Wishlist for a bundle-only transport mode 2007-11-21 16:36 ` Johannes Schindelin @ 2007-11-21 16:44 ` Santi Béjar 0 siblings, 0 replies; 33+ messages in thread From: Santi Béjar @ 2007-11-21 16:44 UTC (permalink / raw) To: Johannes Schindelin; +Cc: Git Mailing List On Nov 21, 2007 5:36 PM, Johannes Schindelin <Johannes.Schindelin@gmx.de> wrote: > Hi, > > On Wed, 21 Nov 2007, Santi B?jar wrote: > > > On Nov 21, 2007 4:59 PM, Johannes Schindelin <Johannes.Schindelin@gmx.de> wrote: > > > > > On Wed, 21 Nov 2007, Santi B?jar wrote: > > > > > > > 1) git-clone does not accept a bundle file, even if git-fetch does. > > > > I've made a patch to use git-fetch in git-clone for this. > > > > > > This, along with rewriting git-clone as a very thin wrapper over > > > git-init, -remote and -fetch, is a really low hanging fruit. > > > > For the basic/normal mode it can be a very thin wrapper but you have to > > support --local, --shared, --reference... > > That is not all that difficult. I did not say it was difficult, I said it was not a very thin wrapper. > > > > > 2) The bundles created with "git bundle" does not record the HEAD, > > > > they resolve the symbolic name to a branch name. > > > > > > It imitates ls-remote output. > > > > No, it does not. > > > > With a newly created project with one commit: > > > > $ git ls-remote git.git > > b71992713c17c3a29f9566e1b50e8cf402375faf HEAD > > b71992713c17c3a29f9566e1b50e8cf402375faf refs/heads/master > > > > $ git bundle create git.bdl HEAD master > > > > $ git bundle list-heads git.bdl > > b71992713c17c3a29f9566e1b50e8cf402375faf refs/heads/master > > b71992713c17c3a29f9566e1b50e8cf402375faf refs/heads/master > > Ah, I misunderstood. Maybe because of my non-native english :-) > I thought you were expecting that the first line > would read > > refs/heads/master HEAD or ref: refs/heads/master HEAD That would be perfect, but it is a different story. > > Alas, this behaviour stems from dwim_ref() returning "refs/heads/master" > as real ref. > > I am not quite sure how to solve this, though. Let me see what I can come > up with. Thank you. Santi ^ permalink raw reply [flat|nested] 33+ messages in thread
* [PATCH] bundle create: keep symbolic refs' names instead of resolving them 2007-11-21 16:15 ` Santi Béjar 2007-11-21 16:36 ` Johannes Schindelin @ 2007-11-21 16:53 ` Johannes Schindelin 2007-11-22 12:03 ` Johannes Schindelin 2007-11-22 12:24 ` [REPLACEMENT PATCH] " Johannes Schindelin 1 sibling, 2 replies; 33+ messages in thread From: Johannes Schindelin @ 2007-11-21 16:53 UTC (permalink / raw) To: Santi Béjar; +Cc: Git Mailing List [-- Attachment #1: Type: TEXT/PLAIN, Size: 2328 bytes --] When creating a bundle, symbolic refs used to be resolved to the non-symbolic refs they point to before being written to the list of contained refs. I.e. "git bundle create a1.bundle HEAD master" would show something like 388afe7881b33102fada216dd07806728773c011 refs/heads/master 388afe7881b33102fada216dd07806728773c011 refs/heads/master Introduce a special handling so that the symbolic refs are listed with the names passed on the command line. Noticed by Santi Béjar. Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de> --- bundle.c | 13 ++++++++----- 1 files changed, 8 insertions(+), 5 deletions(-) diff --git a/bundle.c b/bundle.c index e4d60cd..5e8242f 100644 --- a/bundle.c +++ b/bundle.c @@ -6,6 +6,7 @@ #include "revision.h" #include "list-objects.h" #include "run-command.h" +#include "refs.h" static const char bundle_signature[] = "# v2 git bundle\n"; @@ -231,12 +232,17 @@ int create_bundle(struct bundle_header *header, const char *path, for (i = 0; i < revs.pending.nr; i++) { struct object_array_entry *e = revs.pending.objects + i; unsigned char sha1[20]; - char *ref; + const char *ref; + int flag; if (e->item->flags & UNINTERESTING) continue; - if (dwim_ref(e->name, strlen(e->name), sha1, &ref) != 1) + ref = resolve_ref(e->name, sha1, 1, &flag); + if (!ref) continue; + if (flag & REF_ISSYMREF) + ref = e->name; + /* * Make sure the refs we wrote out is correct; --max-count and * other limiting options could have prevented all the tips @@ -249,7 +255,6 @@ int create_bundle(struct bundle_header *header, const char *path, if (!(e->item->flags & SHOWN) && e->item->type == OBJ_COMMIT) { warning("ref '%s' is excluded by the rev-list options", e->name); - free(ref); continue; } /* @@ -280,7 +285,6 @@ int create_bundle(struct bundle_header *header, const char *path, obj->flags |= SHOWN; add_pending_object(&revs, obj, e->name); } - free(ref); continue; } @@ -289,7 +293,6 @@ int create_bundle(struct bundle_header *header, const char *path, write_or_die(bundle_fd, " ", 1); write_or_die(bundle_fd, ref, strlen(ref)); write_or_die(bundle_fd, "\n", 1); - free(ref); } if (!ref_count) die ("Refusing to create empty bundle."); -- 1.5.3.6.1977.g54d30 ^ permalink raw reply related [flat|nested] 33+ messages in thread
* Re: [PATCH] bundle create: keep symbolic refs' names instead of resolving them 2007-11-21 16:53 ` [PATCH] bundle create: keep symbolic refs' names instead of resolving them Johannes Schindelin @ 2007-11-22 12:03 ` Johannes Schindelin 2007-11-22 12:24 ` [REPLACEMENT PATCH] " Johannes Schindelin 1 sibling, 0 replies; 33+ messages in thread From: Johannes Schindelin @ 2007-11-22 12:03 UTC (permalink / raw) To: Santi Béjar; +Cc: Git Mailing List Hi, On Wed, 21 Nov 2007, Johannes Schindelin wrote: > > When creating a bundle, symbolic refs used to be resolved to the > non-symbolic refs they point to before being written to the list > of contained refs. I.e. "git bundle create a1.bundle HEAD master" > would show something like > > 388afe7881b33102fada216dd07806728773c011 refs/heads/master > 388afe7881b33102fada216dd07806728773c011 refs/heads/master Aaargh. My patch broke "git bundle create x master". I somehow believed that resolve_ref () would turn "master" into "refs/heads/master", which it does not do. So please ignore this patch. Ciao, Dscho ^ permalink raw reply [flat|nested] 33+ messages in thread
* [REPLACEMENT PATCH] bundle create: keep symbolic refs' names instead of resolving them 2007-11-21 16:53 ` [PATCH] bundle create: keep symbolic refs' names instead of resolving them Johannes Schindelin 2007-11-22 12:03 ` Johannes Schindelin @ 2007-11-22 12:24 ` Johannes Schindelin 1 sibling, 0 replies; 33+ messages in thread From: Johannes Schindelin @ 2007-11-22 12:24 UTC (permalink / raw) To: Santi B?jar, gitster; +Cc: Git Mailing List [-- Attachment #1: Type: TEXT/PLAIN, Size: 2101 bytes --] When creating a bundle, symbolic refs used to be resolved to the non-symbolic refs they point to before being written to the list of contained refs. I.e. "git bundle create a1.bundle HEAD master" would show something like 388afe7881b33102fada216dd07806728773c011 refs/heads/master 388afe7881b33102fada216dd07806728773c011 refs/heads/master instead of 388afe7881b33102fada216dd07806728773c011 HEAD 388afe7881b33102fada216dd07806728773c011 refs/heads/master Introduce a special handling so that the symbolic refs are listed with the names passed on the command line. Noticed by Santi Béjar. Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de> --- ... and this patch actually does not break the test suite. bundle.c | 9 ++++++++- 1 files changed, 8 insertions(+), 1 deletions(-) diff --git a/bundle.c b/bundle.c index e4d60cd..9b9b916 100644 --- a/bundle.c +++ b/bundle.c @@ -6,6 +6,7 @@ #include "revision.h" #include "list-objects.h" #include "run-command.h" +#include "refs.h" static const char bundle_signature[] = "# v2 git bundle\n"; @@ -232,11 +233,17 @@ int create_bundle(struct bundle_header *header, const char *path, struct object_array_entry *e = revs.pending.objects + i; unsigned char sha1[20]; char *ref; + const char *display_ref; + int flag; if (e->item->flags & UNINTERESTING) continue; if (dwim_ref(e->name, strlen(e->name), sha1, &ref) != 1) continue; + if (!resolve_ref(e->name, sha1, 1, &flag)) + flag = 0; + display_ref = (flag & REF_ISSYMREF) ? e->name : ref; + /* * Make sure the refs we wrote out is correct; --max-count and * other limiting options could have prevented all the tips @@ -287,7 +294,7 @@ int create_bundle(struct bundle_header *header, const char *path, ref_count++; write_or_die(bundle_fd, sha1_to_hex(e->item->sha1), 40); write_or_die(bundle_fd, " ", 1); - write_or_die(bundle_fd, ref, strlen(ref)); + write_or_die(bundle_fd, display_ref, strlen(display_ref)); write_or_die(bundle_fd, "\n", 1); free(ref); } -- 1.5.3.6.1977.g54d30 ^ permalink raw reply related [flat|nested] 33+ messages in thread
* Re: Wishlist for a bundle-only transport mode 2007-11-21 15:59 ` Johannes Schindelin 2007-11-21 16:15 ` Santi Béjar @ 2007-11-21 16:23 ` Kristian Høgsberg 2007-11-21 17:07 ` Johannes Schindelin 1 sibling, 1 reply; 33+ messages in thread From: Kristian Høgsberg @ 2007-11-21 16:23 UTC (permalink / raw) To: Johannes Schindelin; +Cc: Santi Béjar, Git Mailing List On Wed, 2007-11-21 at 15:59 +0000, Johannes Schindelin wrote: > Hi, > > On Wed, 21 Nov 2007, Santi B?jar wrote: > > > 1) git-clone does not accept a bundle file, even if git-fetch does. I've > > made a patch to use git-fetch in git-clone for this. > > This, along with rewriting git-clone as a very thin wrapper over git-init, > -remote and -fetch, is a really low hanging fruit. > > Or maybe go the full nine yards and build it in. Should be a breeze now, > given parse_options() and run_command(). I started doing this, which is pretty stupid as I'm pressed to find time to finish up builtin-commit. Nevertheless, could you elaborate on the plan here? How would you rewrite it to just use remote and fetch? I just finished the boilerplate option parsing stuff (patch below) and started reading the core of git-clone.sh, but if most of this can be replaced I'd like to hear about it :) cheers, Kristian >From ccfa6b7b6c0bad98201166db3f91760b423ab0c9 Mon Sep 17 00:00:00 2001 From: =?utf-8?q?Kristian=20H=C3=B8gsberg?= <krh@redhat.com> Date: Sun, 18 Nov 2007 18:48:04 -0500 Subject: [PATCH] builtin-clone: first steps, up to and including git-init. --- Makefile | 2 +- builtin-clone.c | 286 +++++++++++++++++++++++++ builtin-init-db.c | 90 ++++---- builtin.h | 1 + cache.h | 4 + git-clone.sh => contrib/examples/git-clone.sh | 0 git.c | 1 + 7 files changed, 341 insertions(+), 43 deletions(-) create mode 100644 builtin-clone.c rename git-clone.sh => contrib/examples/git-clone.sh (100%) diff --git a/Makefile b/Makefile index 4d23d12..f39b7e8 100644 --- a/Makefile +++ b/Makefile @@ -213,7 +213,6 @@ BASIC_LDFLAGS = SCRIPT_SH = \ git-bisect.sh git-checkout.sh \ - git-clone.sh \ git-merge-one-file.sh git-mergetool.sh git-parse-remote.sh \ git-pull.sh git-rebase.sh git-rebase--interactive.sh \ git-repack.sh git-request-pull.sh \ @@ -327,6 +326,7 @@ BUILTIN_OBJS = \ builtin-checkout-index.o \ builtin-check-ref-format.o \ builtin-clean.o \ + builtin-clone.o \ builtin-commit.o \ builtin-commit-tree.o \ builtin-count-objects.o \ diff --git a/builtin-clone.c b/builtin-clone.c new file mode 100644 index 0000000..8a569e0 --- /dev/null +++ b/builtin-clone.c @@ -0,0 +1,286 @@ +/* + * Builtin "git clone" + * + * Copyright (c) 2007 Kristian Høgsberg <krh@redhat.com> + * Based on git-commit.sh by Junio C Hamano and Linus Torvalds + * + * Clone a repository into a different directory that does not yet exist. + */ + +#include "cache.h" +#include "parse-options.h" + +/* + * Implementation notes: + * - dropping use-separate-remote and no-separate-remote compatibility + * + */ +static const char * const builtin_clone_usage[] = { + "git-clone [options] [--] <repo> [<dir>]", + NULL +}; + +static int option_quiet, option_no_checkout, option_bare; +static int option_local, option_no_hardlinks, option_shared, option_depth; +static char *option_template, *option_reference, *option_origin; +static char *option_upload_pack; + +static struct option builtin_clone_options[] = { + OPT__QUIET(&option_quiet), + OPT_BOOLEAN('n', "no-checkout", &option_no_checkout, + "don't create a checkout"), + OPT_BOOLEAN(0, "bare", &option_bare, "create a bare repository"), + OPT_BOOLEAN(0, "naked", &option_bare, "create a bare repository"), + OPT_BOOLEAN('l', "local", &option_local, + "to clone from a local repository"), + OPT_BOOLEAN(0, "no-hardlinks", &option_no_hardlinks, + "don't use local hardlinks, always copy"), + OPT_BOOLEAN('s', "shared", &option_shared, + "setup as shared repository"), + OPT_STRING(0, "template", &option_template, "path", + "path the template repository"), + OPT_STRING(0, "reference", &option_reference, "repo", + "reference repository"), + OPT_STRING('o', "origin", &option_origin, "branch", + "use <branch> instead or 'origin' to track upstream"), + OPT_STRING('u', "upload-pack", &option_upload_pack, "path", + "path to git-upload-pack on the remote"), + OPT_INTEGER(0, "depth", &option_depth, + "create a shallow clone of that depth"), + + OPT_END() +}; + +static char *get_repo_path(const char *repo) +{ + const char *path; + struct stat buf; + + path = mkpath("%s/.git", repo); + if (!stat(path, &buf) && S_ISDIR(buf.st_mode)) + return xstrdup(make_absolute_path(path)); + + path = mkpath("%s.git", repo); + if (!stat(path, &buf) && S_ISDIR(buf.st_mode)) + return xstrdup(make_absolute_path(path)); + + if (!stat(repo, &buf) && S_ISDIR(buf.st_mode)) + return xstrdup(make_absolute_path(repo)); + + return NULL; +} + +static char *guess_dir_name(const char *repo) +{ + const char *p, *start, *end, *limit; + int after_slash_or_colon; + + /* Guess dir name from repository: strip trailing '/', + * strip trailing '[:/]*git', strip leading '.*[/:]'. */ + + after_slash_or_colon = 1; + limit = repo + strlen(repo); + start = repo; + end = limit; + for (p = repo; p < limit; p++) { + if (!prefixcmp(p, ".git")) { + if (!after_slash_or_colon) + end = p; + p += 3; + } else if (*p == '/' || *p == ':') { + if (end == limit) + end = p; + after_slash_or_colon = 1; + } else if (after_slash_or_colon) { + start = p; + end = limit; + after_slash_or_colon = 0; + } + } + + return xstrndup(start, end - start); +} + +static void +setup_reference(void) +{ + struct stat buf; + const char *ref_git, *alternates; + int fd; + + if (!option_reference) + return; + + if (!stat(mkpath("%s/.git/objects", option_reference), &buf) && + S_ISDIR(buf.st_mode)) + ref_git = mkpath("%s/.git", option_reference); + else if (!stat(mkpath("%s/objects", option_reference), &buf) && + S_ISDIR(buf.st_mode)) + ref_git = option_reference; + else + die("reference repository '%s' is not a local directory.", + option_reference); + + ref_git = make_absolute_path(ref_git); + + fd = open(git_path("objects/info/alternates"), + O_WRONLY | O_CREAT, 0666); + if (fd < 0) + die("could not create alternates file\n"); + alternates = mkpath("%s/objects\n", ref_git); + write_or_die(fd, alternates, strlen(alternates)); + if (close(fd) < 0) + die("could not close alternates file\n"); + + /* This part is going to be tricky, since it deals with two + * repositories. Most code in git works on global state + * assumed to be coming from the one active repository, but + * here we want to do for-each-ref in one repository and say + * update-ref in another. We could just say set_git_dir() and + * then say for-each-ref and store the refs in an array and + * the say set_git_dir() again to switch to the repository + * we're creating and then write out the refs using update-ref. */ + + /* + + echo "$ref_git/objects" >"$GIT_DIR/objects/info/alternates" + ( + GIT_DIR="$ref_git" git for-each-ref \ + --format='%(objectname) %(*objectname)' + ) | + while read a b + do + test -z "$a" || + git update-ref "refs/reference-tmp/$a" "$a" + test -z "$b" || + git update-ref "refs/reference-tmp/$b" "$b" + done + + */ +} + +static void +cleanup_reference(void) +{ + /* + test -d "$GIT_DIR/refs/reference-tmp" && + rm -fr "$GIT_DIR/refs/reference-tmp" + */ +} + +static void +clone_local(const char *path) +{ + /* local hardlink magic */ + printf("local, from %s\n", path); +} + +static void +clone_rsync(const char *repo) +{ + printf("rsync, from %s\n", repo); + if (option_depth > 0) + die("shallow over rsync not supported"); +} + +static void +clone_native(const char *repo) +{ + printf("native git, from %s\n", repo); +} + +static void +clone_curl(const char *repo) +{ + printf("curl, from %s\n", repo); + if (option_depth > 0) + die("shallow over rsync not supported"); +} + +int cmd_clone(int argc, const char **argv, const char *prefix) +{ + int use_local_hardlinks = 1; + int use_separate_remote = 1; + struct stat buf; + const char *repo, *work_tree, *git_dir; + char *path, *dir; + + argc = parse_options(argc, argv, builtin_clone_options, + builtin_clone_usage, 0); + + if (argc == 0) + die("You must specify a repository to clone."); + + if (option_no_hardlinks) + use_local_hardlinks = 0; + + if (option_bare) { + if (option_origin) + die("--bare and --origin %s options are incompatible.", + option_origin); + option_no_checkout = 1; + use_separate_remote = 0; + } + + if (!option_origin) + option_origin = "origin"; + + repo = argv[0]; + path = get_repo_path(repo); + + if (argc == 2) { + dir = xstrdup(argv[1]); + } else { + dir = guess_dir_name(repo); + } + + printf("repo: %s, path: %s\n", repo, path); + printf("dir: %s\n", dir); + + if (!stat(dir, &buf)) + die("destination directory '%s' already exists.", dir); + + if (option_bare) + work_tree = NULL; + else { + work_tree = getenv("GIT_WORK_TREE"); + if (work_tree && !stat(work_tree, &buf)) + die("working tree '%s' already exists.", work_tree); + } + + if (mkdir(dir, 0755)) + die("could not create repository dir '%s'.", dir); + if (work_tree && mkdir(work_tree, 0755)) + die("could not create work tree dir '%s'.", work_tree); + + if (option_bare || work_tree) + git_dir = xstrdup(dir); + else + git_dir = xstrdup(mkpath("%s/.git", dir)); + + set_git_dir(make_absolute_path(git_dir)); + init_db(git_dir, option_template, option_quiet ? INIT_DB_QUIET : 0); + + if (option_bare) + git_config_set("core.bare", "true"); + + setup_reference(); + + if (path != NULL) { + clone_local(path); + } else if (!prefixcmp(repo, "rsync://")) { + clone_rsync(repo); + } else if (!prefixcmp(repo, "https://") || + !prefixcmp(repo, "http://") || + !prefixcmp(repo, "ftp://")) { + clone_curl(repo); + } else { + clone_native(repo); + } + + cleanup_reference(); + + + + return 0; +} diff --git a/builtin-init-db.c b/builtin-init-db.c index e1393b8..0ddfb46 100644 --- a/builtin-init-db.c +++ b/builtin-init-db.c @@ -330,49 +330,11 @@ static void guess_repository_type(const char *git_dir) return; } -static const char init_db_usage[] = -"git-init [-q | --quiet] [--template=<template-directory>] [--shared]"; - -/* - * If you want to, you can share the DB area with any number of branches. - * That has advantages: you can save space by sharing all the SHA1 objects. - * On the other hand, it might just make lookup slower and messier. You - * be the judge. The default case is to have one DB per managed directory. - */ -int cmd_init_db(int argc, const char **argv, const char *prefix) +int init_db(const char *git_dir, const char *template_dir, unsigned int flags) { - const char *git_dir; const char *sha1_dir; - const char *template_dir = NULL; char *path; - int len, i, reinit; - int quiet = 0; - - for (i = 1; i < argc; i++, argv++) { - const char *arg = argv[1]; - if (!prefixcmp(arg, "--template=")) - template_dir = arg+11; - else if (!strcmp(arg, "--shared")) - shared_repository = PERM_GROUP; - else if (!prefixcmp(arg, "--shared=")) - shared_repository = git_config_perm("arg", arg+9); - else if (!strcmp(arg, "-q") || !strcmp(arg, "--quiet")) - quiet = 1; - else - usage(init_db_usage); - } - - /* - * GIT_WORK_TREE makes sense only in conjunction with GIT_DIR - * without --bare. Catch the error early. - */ - git_dir = getenv(GIT_DIR_ENVIRONMENT); - if ((!git_dir || is_bare_repository_cfg == 1) - && getenv(GIT_WORK_TREE_ENVIRONMENT)) - die("%s (or --work-tree=<directory>) not allowed without " - "specifying %s (or --git-dir=<directory>)", - GIT_WORK_TREE_ENVIRONMENT, - GIT_DIR_ENVIRONMENT); + int len, reinit; guess_repository_type(git_dir); @@ -388,7 +350,6 @@ int cmd_init_db(int argc, const char **argv, const char *prefix) /* * Set up the default .git directory contents */ - git_dir = getenv(GIT_DIR_ENVIRONMENT); if (!git_dir) git_dir = DEFAULT_GIT_DIR_ENVIRONMENT; safe_create_dir(git_dir, 0); @@ -427,7 +388,7 @@ int cmd_init_db(int argc, const char **argv, const char *prefix) git_config_set("receive.denyNonFastforwards", "true"); } - if (!quiet) + if (!(flags & INIT_DB_QUIET)) printf("%s%s Git repository in %s/\n", reinit ? "Reinitialized existing" : "Initialized empty", shared_repository ? " shared" : "", @@ -435,3 +396,48 @@ int cmd_init_db(int argc, const char **argv, const char *prefix) return 0; } + +static const char init_db_usage[] = +"git-init [-q | --quiet] [--template=<template-directory>] [--shared]"; + +/* + * If you want to, you can share the DB area with any number of branches. + * That has advantages: you can save space by sharing all the SHA1 objects. + * On the other hand, it might just make lookup slower and messier. You + * be the judge. The default case is to have one DB per managed directory. + */ +int cmd_init_db(int argc, const char **argv, const char *prefix) +{ + const char *git_dir; + const char *template_dir = NULL; + unsigned int flags = 0; + int i; + + for (i = 1; i < argc; i++, argv++) { + const char *arg = argv[1]; + if (!prefixcmp(arg, "--template=")) + template_dir = arg+11; + else if (!strcmp(arg, "--shared")) + shared_repository = PERM_GROUP; + else if (!prefixcmp(arg, "--shared=")) + shared_repository = git_config_perm("arg", arg+9); + else if (!strcmp(arg, "-q") || !strcmp(arg, "--quiet")) + flags |= INIT_DB_QUIET; + else + usage(init_db_usage); + } + + /* + * GIT_WORK_TREE makes sense only in conjunction with GIT_DIR + * without --bare. Catch the error early. + */ + git_dir = getenv(GIT_DIR_ENVIRONMENT); + if ((!git_dir || is_bare_repository_cfg == 1) + && getenv(GIT_WORK_TREE_ENVIRONMENT)) + die("%s (or --work-tree=<directory>) not allowed without " + "specifying %s (or --git-dir=<directory>)", + GIT_WORK_TREE_ENVIRONMENT, + GIT_DIR_ENVIRONMENT); + + return init_db(git_dir, template_dir, flags); +} diff --git a/builtin.h b/builtin.h index 6f01e96..8e59778 100644 --- a/builtin.h +++ b/builtin.h @@ -24,6 +24,7 @@ extern int cmd_check_attr(int argc, const char **argv, const char *prefix); extern int cmd_check_ref_format(int argc, const char **argv, const char *prefix); extern int cmd_cherry(int argc, const char **argv, const char *prefix); extern int cmd_cherry_pick(int argc, const char **argv, const char *prefix); +extern int cmd_clone(int argc, const char **argv, const char *prefix); extern int cmd_clean(int argc, const char **argv, const char *prefix); extern int cmd_commit(int argc, const char **argv, const char *prefix); extern int cmd_commit_tree(int argc, const char **argv, const char *prefix); diff --git a/cache.h b/cache.h index 510154b..8c5f6af 100644 --- a/cache.h +++ b/cache.h @@ -230,6 +230,10 @@ extern const char *prefix_filename(const char *prefix, int len, const char *path extern void verify_filename(const char *prefix, const char *name); extern void verify_non_filename(const char *prefix, const char *name); +#define INIT_DB_QUIET 0x0001 + +extern int init_db(const char *git_dir, const char *template_dir, unsigned int flags); + #define alloc_nr(x) (((x)+16)*3/2) /* diff --git a/git-clone.sh b/contrib/examples/git-clone.sh similarity index 100% rename from git-clone.sh rename to contrib/examples/git-clone.sh diff --git a/git.c b/git.c index 9606937..9236833 100644 --- a/git.c +++ b/git.c @@ -293,6 +293,7 @@ static void handle_internal_command(int argc, const char **argv) { "check-attr", cmd_check_attr, RUN_SETUP | NEED_WORK_TREE }, { "cherry", cmd_cherry, RUN_SETUP }, { "cherry-pick", cmd_cherry_pick, RUN_SETUP | NEED_WORK_TREE }, + { "clone", cmd_clone }, { "clean", cmd_clean, RUN_SETUP | NEED_WORK_TREE }, { "commit", cmd_commit, RUN_SETUP | NEED_WORK_TREE }, { "commit-tree", cmd_commit_tree, RUN_SETUP }, -- 1.5.3.4 ^ permalink raw reply related [flat|nested] 33+ messages in thread
* Re: Wishlist for a bundle-only transport mode 2007-11-21 16:23 ` Wishlist for a bundle-only transport mode Kristian Høgsberg @ 2007-11-21 17:07 ` Johannes Schindelin 0 siblings, 0 replies; 33+ messages in thread From: Johannes Schindelin @ 2007-11-21 17:07 UTC (permalink / raw) To: Kristian Høgsberg; +Cc: Santi Béjar, Git Mailing List Hi, On Wed, 21 Nov 2007, Kristian H?gsberg wrote: > On Wed, 2007-11-21 at 15:59 +0000, Johannes Schindelin wrote: > > Hi, > > > > On Wed, 21 Nov 2007, Santi B?jar wrote: > > > > > 1) git-clone does not accept a bundle file, even if git-fetch does. I've > > > made a patch to use git-fetch in git-clone for this. > > > > This, along with rewriting git-clone as a very thin wrapper over git-init, > > -remote and -fetch, is a really low hanging fruit. > > > > Or maybe go the full nine yards and build it in. Should be a breeze now, > > given parse_options() and run_command(). > > I started doing this, which is pretty stupid as I'm pressed to find time > to finish up builtin-commit. Nevertheless, could you elaborate on the > plan here? How would you rewrite it to just use remote and fetch? I > just finished the boilerplate option parsing stuff (patch below) and > started reading the core of git-clone.sh, but if most of this can be > replaced I'd like to hear about it :) After handling the options like --reference, and except for special handling of a local clone (not via file:// protocol), it should be as easy as git remote add -f origin $url && case "$no_checkout" in t) ;; *) git checkout -f -b master remotes/origin/HEAD ;; esac (Of course I'd use run_command() for this.) I would avoid at all costs to reimplement the different methods for the different protocols. Ciao, Dscho ^ permalink raw reply [flat|nested] 33+ messages in thread
* Re: Wishlist for a bundle-only transport mode 2007-11-21 14:54 Wishlist for a bundle-only transport mode Santi Béjar 2007-11-21 15:04 ` Jakub Narebski 2007-11-21 15:59 ` Johannes Schindelin @ 2007-11-21 17:06 ` Jakub Narebski 2007-11-21 17:29 ` Johannes Schindelin 2 siblings, 1 reply; 33+ messages in thread From: Jakub Narebski @ 2007-11-21 17:06 UTC (permalink / raw) To: git [Cc: Santi Béjar <sbejar@gmail.com>, git@vger.kernel.org] Santi Béjar wrote: > 1) git-clone does not accept a bundle file, even if git-fetch does. > I've made a patch to use git-fetch in git-clone for this. [...] > 3) I can "git fetch" a bundle but I cannot "git push" a bundle We would also need "git ls-remote <bundle>" and "git fsck <bundle>" to demote git-bundle to porcelain status :-) -- Jakub Narebski Warsaw, Poland ShadeHawk on #git ^ permalink raw reply [flat|nested] 33+ messages in thread
* Re: Wishlist for a bundle-only transport mode 2007-11-21 17:06 ` Jakub Narebski @ 2007-11-21 17:29 ` Johannes Schindelin 0 siblings, 0 replies; 33+ messages in thread From: Johannes Schindelin @ 2007-11-21 17:29 UTC (permalink / raw) To: Jakub Narebski; +Cc: git Hi, On Wed, 21 Nov 2007, Jakub Narebski wrote: > We would also need "git ls-remote <bundle>" and "git fsck <bundle>" to > demote git-bundle to porcelain status :-) git ls-remote <bundle> worked, last time I checked (15 seconds ago). But git fsck? Since when does something like "git fsck git://repo.or.cz/git.git" work? Besides, "git bundle verify <bundle>" works quite well. Ciao, Dscho ^ permalink raw reply [flat|nested] 33+ messages in thread
end of thread, other threads:[~2007-11-24 19:15 UTC | newest] Thread overview: 33+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2007-11-21 14:54 Wishlist for a bundle-only transport mode Santi Béjar 2007-11-21 15:04 ` Jakub Narebski 2007-11-21 15:24 ` Santi Béjar 2007-11-21 15:46 ` Johannes Schindelin 2007-11-21 16:52 ` Jakub Narebski 2007-11-21 16:59 ` Johannes Schindelin 2007-11-21 17:11 ` Jakub Narebski 2007-11-21 17:26 ` Johannes Schindelin 2007-11-21 17:52 ` Jakub Narebski 2007-11-22 9:42 ` Santi Béjar 2007-11-22 10:02 ` Junio C Hamano 2007-11-23 9:18 ` Jakub Narebski 2007-11-23 9:31 ` Junio C Hamano 2007-11-23 10:04 ` Jakub Narebski 2007-11-23 10:13 ` Santi Béjar 2007-11-23 12:18 ` Johannes Schindelin 2007-11-23 15:06 ` Junio C Hamano 2007-11-23 15:34 ` Santi Béjar 2007-11-23 16:05 ` Junio C Hamano 2007-11-23 16:39 ` Santi Béjar 2007-11-24 19:15 ` Junio C Hamano 2007-11-23 19:09 ` Jakub Narebski 2007-11-21 15:59 ` Johannes Schindelin 2007-11-21 16:15 ` Santi Béjar 2007-11-21 16:36 ` Johannes Schindelin 2007-11-21 16:44 ` Santi Béjar 2007-11-21 16:53 ` [PATCH] bundle create: keep symbolic refs' names instead of resolving them Johannes Schindelin 2007-11-22 12:03 ` Johannes Schindelin 2007-11-22 12:24 ` [REPLACEMENT PATCH] " Johannes Schindelin 2007-11-21 16:23 ` Wishlist for a bundle-only transport mode Kristian Høgsberg 2007-11-21 17:07 ` Johannes Schindelin 2007-11-21 17:06 ` Jakub Narebski 2007-11-21 17:29 ` Johannes Schindelin
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).