threads / discuss / 14120

git-fetch remote tag to local branch fails

Subject: git-fetch remote tag to local branch fails

## tl;dr

10 messages between Jun 24, 2008 and Jun 25, 2008.

replies: 9people: 4as markdown or json

Klas Lindberg· Jun 24, 2008, 12:17 UTC · lore
Hi

I have a repository "bogustree" that contains tags "test_tag" and "foo_tag" (both on the same branch, with "test_tag" pointing to an older commit). I also have repository "R", which contains "test_tag" from "bogustree" and a branch "b" created from "test_tag". The active branch in R is "master".

Now I want to do the following from R:
git-fetch bogustree refs/tags/foo_tag:refs/heads/b

but this fails with the message given below. The interesting part is that git-fetch tries to write a "non-commit object" and indeed I have no idea what this thing is (the commit pointed to by "foo_tag" has commit ID cab0a25388f1884a1ab16bd0d66f877c0b36f1d5). Another interesting detail is that the command fails and then continues anyway. That seems wrong in itself.

# remote: Counting objects: 6, done. # remote: Compressing objects: 100% (2/2), done. # remote: Total 4 (delta 0), reused 0 (delta 0) # Unpacking objects: 100% (4/4), done. # error: Trying to write non-commit object 5f61233bc5dad0f3e25ecea65457f5bb528174d2 to branch refs/heads/B # From /home/qliklas/bogustree/b/b # 72f0622..5f61233 foo_tag -> b # From /home/qliklas/bogustree/b/b # * [new tag] foo_tag -> foo_tag # * [new tag] test_tag -> test_tag

Why can't I fetch like this? The manual page for git-fetch says that
       <refspec>
              The canonical format of a <refspec> parameter is +?<src>:<dst>;
              that is, an optional plus +, followed by the source ref,
              followed by a colon :, followed by the destination ref.
              The remote ref that matches <src> is fetched, and if <dst> is
              not empty string, the local ref that matches it is fast
              forwarded using <src>. Again, if the optional plus + is used,
              the local ref is updated even if it does not result in a fast
              forward update.
so I think it should be OK?
BR / Klas
Santi Béjar· Jun 24, 2008, 13:38 UTC · re: Klas Lindberg · lore

Re: git-fetch remote tag to local branch fails

On Tue, Jun 24, 2008 at 14:17, Klas Lindberg <klas.lindberg@gmail.com> wrote:
Show 17 quoted lines
> Hi
>
> I have a repository "bogustree" that contains tags "test_tag" and
> "foo_tag" (both on the same branch, with "test_tag" pointing to an
> older commit).
> I also have repository "R", which contains "test_tag" from "bogustree"
> and a branch "b" created from "test_tag". The active branch in R is
> "master".
>
> Now I want to do the following from R:
>
> git-fetch bogustree refs/tags/foo_tag:refs/heads/b
>
> but this fails with the message given below. The interesting part is
> that git-fetch tries to write a "non-commit object" and indeed I have
> no idea what this thing is (the commit pointed to by "foo_tag" has
> commit ID cab0a25388f1884a1ab16bd0d66f877c0b36f1d5).

non-commit object is an object that is not a commit, like a tag, a blob or a tree, and you are trying to write a tag in refs/heads/. Only commits objects (no tags) are allowed in refs/heads/.

Show 15 quoted lines
> Another
> interesting detail is that the command fails and then continues
> anyway. That seems wrong in itself.
>
> # remote: Counting objects: 6, done.
> # remote: Compressing objects: 100% (2/2), done.
> # remote: Total 4 (delta 0), reused 0 (delta 0)
> # Unpacking objects: 100% (4/4), done.
> # error: Trying to write non-commit object
> 5f61233bc5dad0f3e25ecea65457f5bb528174d2 to branch refs/heads/B
> # From /home/qliklas/bogustree/b/b
> #    72f0622..5f61233  foo_tag    -> b
> # From /home/qliklas/bogustree/b/b
> #  * [new tag]         foo_tag    -> foo_tag
> #  * [new tag]         test_tag   -> test_tag

Are you sure it is written as a branch? What is the output of "git tag -l" and "git branch -a"?

Show 15 quoted lines
>
> Why can't I fetch like this? The manual page for git-fetch says that
>
>       <refspec>
>              The canonical format of a <refspec> parameter is +?<src>:<dst>;
>              that is, an optional plus +, followed by the source ref,
>              followed by a colon :, followed by the destination ref.
>
>              The remote ref that matches <src> is fetched, and if <dst> is
>              not empty string, the local ref that matches it is fast
>              forwarded using <src>. Again, if the optional plus + is used,
>              the local ref is updated even if it does not result in a fast
>              forward update.
>
> so I think it should be OK?
as long as <src> are commit objects.
Santi
Klas Lindberg· Jun 24, 2008, 14:01 UTC · re: Santi Béjar · lore

Re: git-fetch remote tag to local branch fails

Hello
> git tag -l

foo_tag test_tag

>
> git branch -a
>

At this point, I can create the branch "b" from "foo_tag", so the fetch did get me a remote tag. It just didn't update a local branch with the contents (or create a new one).

Something that also confuses me is that if branch "b" already exists, then
> git-pull bogustree refs/tags/foo_tag:refs/heads/b
actually does update branch "b". I find the behaviour quite inconsistent.

Unfortunately it isn't a solution for me to fetch tags and then create branches from the tags. I need to be able to update existing branches, and I have to do that without first making such a branch the current branch.

Any suggestions?
/Klas
On Tue, Jun 24, 2008 at 3:38 PM, Santi Béjar <sbejar@gmail.com> wrote:
Show 64 quoted lines
> On Tue, Jun 24, 2008 at 14:17, Klas Lindberg <klas.lindberg@gmail.com> wrote:
>> Hi
>>
>> I have a repository "bogustree" that contains tags "test_tag" and
>> "foo_tag" (both on the same branch, with "test_tag" pointing to an
>> older commit).
>> I also have repository "R", which contains "test_tag" from "bogustree"
>> and a branch "b" created from "test_tag". The active branch in R is
>> "master".
>>
>> Now I want to do the following from R:
>>
>> git-fetch bogustree refs/tags/foo_tag:refs/heads/b
>>
>> but this fails with the message given below. The interesting part is
>> that git-fetch tries to write a "non-commit object" and indeed I have
>> no idea what this thing is (the commit pointed to by "foo_tag" has
>> commit ID cab0a25388f1884a1ab16bd0d66f877c0b36f1d5).
>
> non-commit object is an object that is not a commit, like a tag, a
> blob or a tree, and you are trying to write a tag in refs/heads/. Only
> commits objects (no tags) are allowed in refs/heads/.
>
>
>> Another
>> interesting detail is that the command fails and then continues
>> anyway. That seems wrong in itself.
>>
>> # remote: Counting objects: 6, done.
>> # remote: Compressing objects: 100% (2/2), done.
>> # remote: Total 4 (delta 0), reused 0 (delta 0)
>> # Unpacking objects: 100% (4/4), done.
>> # error: Trying to write non-commit object
>> 5f61233bc5dad0f3e25ecea65457f5bb528174d2 to branch refs/heads/B
>> # From /home/qliklas/bogustree/b/b
>> #    72f0622..5f61233  foo_tag    -> b
>> # From /home/qliklas/bogustree/b/b
>> #  * [new tag]         foo_tag    -> foo_tag
>> #  * [new tag]         test_tag   -> test_tag
>
> Are you sure it is written as a branch? What is the output of "git tag
> -l" and "git branch -a"?
>
>
>>
>> Why can't I fetch like this? The manual page for git-fetch says that
>>
>>       <refspec>
>>              The canonical format of a <refspec> parameter is +?<src>:<dst>;
>>              that is, an optional plus +, followed by the source ref,
>>              followed by a colon :, followed by the destination ref.
>>
>>              The remote ref that matches <src> is fetched, and if <dst> is
>>              not empty string, the local ref that matches it is fast
>>              forwarded using <src>. Again, if the optional plus + is used,
>>              the local ref is updated even if it does not result in a fast
>>              forward update.
>>
>> so I think it should be OK?
>
> as long as <src> are commit objects.
>
> Santi
>
Santi Béjar· Jun 24, 2008, 14:27 UTC · re: Klas Lindberg · lore

Re: git-fetch remote tag to local branch fails

On Tue, Jun 24, 2008 at 16:01, Klas Lindberg <klas.lindberg@gmail.com> wrote:
Show 9 quoted lines
> Hello
>
>> git tag -l
> foo_tag
> test_tag
>>
>
>> git branch -a
>>
empty?
Show 10 quoted lines
>
> At this point, I can create the branch "b" from "foo_tag", so the
> fetch did get me a remote tag. It just didn't update a local branch
> with the contents (or create a new one).
>
> Something that also confuses me is that if branch "b" already exists, then
>
>> git-pull bogustree refs/tags/foo_tag:refs/heads/b
>
> actually does update branch "b". I find the behaviour quite inconsistent.
You asked explicitly to update branch b with :refs/heads/b.
Show 6 quoted lines
>
> Unfortunately it isn't a solution for me to fetch tags and then create
> branches from the tags. I need to be able to update existing branches,
> and I have to do that without first making such a branch the current
> branch.
>
If you have to update existing branches from remote branches you can:
git fetch <remote> refs/heads/<remotebranch>:refs/heads/<localbranch>

But normally you have some remote tracking branches, such as how the "origin" remote repository is configured.

Updating from remote tags is not normal, since tags are not supposed to change.
Can you explain why you have to do it this way? Or the whole workflow?
Santi
P.D.: Please, do not toppost.
Klas Lindberg· Jun 24, 2008, 15:31 UTC · re: Santi Béjar · lore

Re: git-fetch remote tag to local branch fails

>>> git branch -a
>>>
>
> empty?
Sorry, my mistake. It lists "master"
Show 5 quoted lines
>>> git-pull bogustree refs/tags/foo_tag:refs/heads/b
>>
>> actually does update branch "b". I find the behaviour quite inconsistent.
>
> You asked explicitly to update branch b with :refs/heads/b.

I'm not sure what you mean. I asked it to update local branch "b" against remote tag "foo_tag" and it did just that. I find it inconsistent that pull can do this, but fetch can't.

> Can you explain why you have to do it this way? Or the whole workflow?

I am looking into the possibility of writing a tool that handles configurations of trees. For instance, I want the tool to be able to consume some version of a configuration and create, update or reset branches in other trees accordingly. The main stumbling block is actually that a lot of git commands have side effects on the working tree (usually because they do something with a "current" branch). In my mind, the user should be able to select a configuration that effectively fast forwards branches in some trees and resets branches in others -- all of it without touching any working trees (unless there is an explicit checkout). The example in this case is that fetching tags to update a branch isn't possible. Pulling *is* possible, but would also update the current branch and the working tree.

/Klas
Klas Lindberg· Jun 24, 2008, 15:36 UTC · re: Klas Lindberg · lore

Re: git-fetch remote tag to local branch fails

> I'm not sure what you mean. I asked it to update local branch "b"
> against remote tag "foo_tag" and it did just that. I find it
> inconsistent that pull can do this, but fetch can't.

I'm sorry. That was plain wrong. It doesn't update the branch from the remote tag when I pull.

Oh well...
Santi Béjar· Jun 24, 2008, 16:11 UTC · re: Klas Lindberg · lore

Re: git-fetch remote tag to local branch fails

On Tue, Jun 24, 2008 at 17:31, Klas Lindberg <klas.lindberg@gmail.com> wrote:
Show 5 quoted lines
>
>> Can you explain why you have to do it this way? Or the whole workflow?
>
> I am looking into the possibility of writing a tool that handles
> configurations of trees.
Maybe you should be using the plumbing commands.
> For instance, I want the tool to be able to
> consume some version of a configuration and create, update or reset
> branches in other trees accordingly.
What are the "other trees"?
Do you mean this?
1. You have a repository with different branches as:
  master
  tree1
  tree2
  ..
2. You want /path/to/tree1 to always checkout tree1
  and the same for treeN
Then
3. In /path/to/treeN/.. you do:
$ git clone /path/to/repo treeN
$ git checkout -b treeN origin/treeN
4. To keep uptodate:
$ git pull
5. The branches for the other trees are always uptodate in origin/*.
> The main stumbling block is actually that a lot of git commands have
> side effects on the working tree (usually because they do something
> with a "current" branch).

Sure. So you have to choose those that don't have these "side effects", you have plenty of them, mainly in the low-level, plumbing commands.

> In my mind, the user should be able to
> select a configuration that effectively fast forwards branches in some
> trees and resets branches in others -- all of it without touching any
> working trees (unless there is an explicit checkout).

Well, if you touch the current branch, for sure, you want to update the working tree.

Maybe you want to keep your local branches up to date with respect their tracking branch?

> The example in this case is that fetching tags to update a branch
> isn't possible.

I don't see the point updating a branch with a tag, but you can make a tool to update a branch with a tag, see for example contrib/examples/git-fetch.sh.

Santi
Klas Lindberg· Jun 25, 2008, 08:50 UTC · re: Santi Béjar · lore

Re: git-fetch remote tag to local branch fails

>> I am looking into the possibility of writing a tool that handles
>> configurations of trees.
>
> Maybe you should be using the plumbing commands.
Yes. It looks like it.
Show 5 quoted lines
>> For instance, I want the tool to be able to
>> consume some version of a configuration and create, update or reset
>> branches in other trees accordingly.
>
> What are the "other trees"?

One tree tracks a configuration file that just contains specs for other trees. The idea is something like this: Given a refspec on the configuration tree, git-view the configuration file and use the contained refspecs to clone/pull/fetch/reset/whatever a bunch of other trees.

Note that I'm not trying to solve the problem addressed by the submodules system in git; I need configuration management.

> Maybe you want to keep your local branches up to date with respect
> their tracking branch?

Well yes, but that is only half of it. One of the scenarios I'm pondering is this: A user wants to take an old configuration based on tags and try some use case that breaks a newer configuration. After the checkout, the working trees will not be "on" any branches (what's the word for that?). Unfortunately, most people seem to think that everything in a VCS happens on a branch. A lot of people will incorrectly assume that they are still on their "working branch" because they didn't check out a different branch! They checked out a tag and, like myself, have muddy ideas about what that actually means in relation to branches. I'd prefer to not have to tell them to try git-lost-found on a 40 different trees to recover commits that they made on non-branches.

I'll have to think more about this. It's not a functionality shortcoming, but a UI one.

> I don't see the point updating a branch with a tag, but you can make a
> tool to update a branch with a tag, see for example
> contrib/examples/git-fetch.sh.

Thank you. I'll have a look at that, but after our conversation I think I was mentally stuck in the land of some other VCS. I know perfectly well that a tag is not just a marker along some branch, but I realize now that I was thinking of it as if it was.

/Klas
Jakub Narebski· Jun 25, 2008, 09:10 UTC · re: Klas Lindberg · lore

Re: git-fetch remote tag to local branch fails

"Klas Lindberg" <klas.lindberg@gmail.com> writes:
> Note that I'm not trying to solve the problem addressed by the
> submodules system in git; I need configuration management.

Why not use one of existing tools (see InterfacesFrontendsAndTools page on Git Wiki, http://git.or.cz/gitwiki/), like IsiSetup, or etckeeper?

-- 
Jakub Narebski
Poland
ShadeHawk on #git
Michael J Gruber· Jun 24, 2008, 14:57 UTC · re: Klas Lindberg · lore

Re: git-fetch remote tag to local branch fails

Klas Lindberg venit, vidit, dixit 24.06.2008 16:01:
Show 18 quoted lines
> Hello
> 
>> git tag -l
> foo_tag
> test_tag
> 
>> git branch -a
>>
> 
> At this point, I can create the branch "b" from "foo_tag", so the
> fetch did get me a remote tag. It just didn't update a local branch
> with the contents (or create a new one).
> 
> Something that also confuses me is that if branch "b" already exists, then
> 
>> git-pull bogustree refs/tags/foo_tag:refs/heads/b
> 
> actually does update branch "b". I find the behaviour quite inconsistent.

You tell git to fetch everything up to the tag you specify, to store those refs into branch b, and then to merge into the current branch. This is what git did (assuming you see the merge in the current branch; if it's b then it has been fast forwarded already).

> Unfortunately it isn't a solution for me to fetch tags and then create
> branches from the tags. I need to be able to update existing branches,
> and I have to do that without first making such a branch the current
> branch.

If I try what you described (using git 1.5.6) in a fresh repo (with one empty commit) I get:

git fetch ../fromrepo refs/tags/testtag:refs/heads/newbranch
warning: no common commits
remote: Counting objects: 18, done.
remote: Compressing objects: 100% (18/18), done.
remote: Total 18 (delta 9), reused 0 (delta 0)
Unpacking objects: 100% (18/18), done.
 From ../fromrepo
  * [new branch]      testtag    -> newbranch
  * [new tag]         testtag    -> testtag

I see a new branch, disconnected from master (no common commits), and a new tag pointing to the head of newbranch. All is well here. Maybe you can set-up a minimal example or share a repo which exposes your problem?

Michael

← back to recent threads