How to create a new branch based on a tag?
Hi,
I would like to create a branch of my own work based on a specific
kernel version(i.e
v2.6.11). I tried with:
Quoted 1 line
git-branch my2.6.11 v2.6.11
error: Object 5dc01c595e6c6ec9ccda4f6f69c131c0dd945f8c is a tree, not a commit
fatal: Needed a single revision
As v2.6.11 is a tree object(tag), git-checkout and git-branch could
not process it. The
only way I know is using git-read-tree to fetch v2.6.11 content into current index and start a branch based on it. Is there any simpler method?
Thanks!
Quoted 10 lines · Ben Lau
Hi,
I would like to create a branch of my own work based on a specific
kernel version(i.e
v2.6.11). I tried with:Quoted 1 line
git-branch my2.6.11 v2.6.11
error: Object
5dc01c595e6c6ec9ccda4f6f69c131c0dd945f8cis a tree, not a commit
fatal: Needed a single revision
What you're after is
git-rev-parse --verify <tagname>^0 > .refs/heads/mynewbranch
"branches" are very lightweight -- it's a ref containing the SHA1 of the commit you want it to be at. So if you find the SHA1 of the commit in gitk or wherever, just
echo SHA1 > .refs/heads/mynewbranch
and you're sorted. Do git-checkout to switch to it.
cheers,
martin
Quoted 24 lines · Martin Langhoff
Quoted 12 lines · Ben Lau
Hi,
I would like to create a branch of my own work based on a specific
kernel version(i.e
v2.6.11). I tried with:Quoted 1 line
git-branch my2.6.11 v2.6.11
error: Object
5dc01c595e6c6ec9ccda4f6f69c131c0dd945f8cis a tree, not a commit
fatal: Needed a single revisionWhat you're after is
git-rev-parse --verify <tagname>^0 > .refs/heads/mynewbranch"branches" are very lightweight -- it's a ref containing the SHA1 of the commit you want it to be at. So if you find the SHA1 of the commit in gitk or wherever, just
Quoted 10 lines
echo SHA1 > .refs/heads/mynewbranch
and you're sorted. Do git-checkout to switch to it.
cheers,
martin
The command complains:
Quoted 1 line
git-rev-parse --verify v2.6.11^
error: Object 5dc01c595e6c6ec9ccda4f6f69c131c0dd945f8c is a tree, not
a commit
fatal: Needed a single revision
I think it need another way to convert a tag/tree object into a commit ?
Quoted 5 lines · Ben Lau
As v2.6.11 is a tree object(tag), git-checkout and git-branch could not process it. The
only way I know is using git-read-tree to fetch v2.6.11 content into current index and start
a branch based on it. Is there any simpler method?
The way you know is as good as it gets. v2.6.11-tree case is really an unfortunate special case.
Quoted 4 lines · Junio C Hamano
Ben Lau <[email protected]> writes:
Quoted 11 lines
Quoted 5 lines
As v2.6.11 is a tree object(tag), git-checkout and git-branch could not process it. The only way I know is using git-read-tree to fetch v2.6.11 content into current index and start a branch based on it. Is there any simpler method?
The way you know is as good as it gets. v2.6.11-tree case is really an unfortunate special case.
What is wrong with the v2.6.11-tree? I just thought it is a duplicate tag of v2.6.11.
Quoted 5 lines · Ben Lau
Quoted 3 lines
The way you know is as good as it gets. v2.6.11-tree case is really an unfortunate special case.
What is wrong with the v2.6.11-tree? I just thought it is a duplicate tag of v2.6.11.
They are not *wrong* per-se. They are tags to tree objects without any associated commit history -- that makes them inappropriate to be used as branch heads.
Linus or somebody authoritative could do:
$ commit=$(echo v2.6.11 | \
git-commit-tree c39ae07f393806ccf406ef966e9a15afc43cc36a)
$ git-tag -s -m 'v2.6.11 canonical "fake" commit' v2.6.11fake $commitand tell everybody interested to have:
1da177e4c3f41524e886b7f1b8a0c1fc7321cac2 xxxxxxxxxx
(where xxxxx... is the value of $commit above) in their info/grafts file. Then we *could* pretend that v2.6.12-rc2's parent is v2.6.11. You could branch off from v2.6.11fake commit and base your development, and later you could merge that into later development history (say, v2.6.14-rc5) if you wanted to.
If Linus does something like the above, the graft probably be better done between the current v2.6.12-rc2 based commit history and the corresponding commit in the history resurrected from BKCVS (torvalds/old-2.6-bkcvs.git). Then you could even base your development on top of v2.4.0 ;-).
Funnily, v2.6.12-rc2 commit in the current history and BKCVS v2.6.12-rc2 commit in the resurrected history have different tree IDs.
I am however not quite sure how useful the above would be, though. EVen between 2.6.11 and 2.6.12-rc2 much have happened, so unless the changes you are making apply to the part that did not change between those two, merge conflict resolution might be quite a chore.
Quoted 51 lines · Junio C Hamano
Quoted 9 lines · Ben Lau
Quoted 5 lines
The way you know is as good as it gets. v2.6.11-tree case is really an unfortunate special case.
What is wrong with the v2.6.11-tree? I just thought it is a duplicate tag of v2.6.11.
They are not *wrong* per-se. They are tags to tree objects without any associated commit history -- that makes them inappropriate to be used as branch heads.
Linus or somebody authoritative could do:
$ commit=$(echo v2.6.11 | \ git-commit-tree c39ae07f393806ccf406ef966e9a15afc43cc36a) $ git-tag -s -m 'v2.6.11 canonical "fake" commit' v2.6.11fake $commitand tell everybody interested to have:
1da177e4c3f41524e886b7f1b8a0c1fc7321cac2xxxxxxxxxx(where xxxxx... is the value of $commit above) in their info/grafts file. Then we *could* pretend that v2.6.12-rc2's parent is v2.6.11. You could branch off from v2.6.11fake commit and base your development, and later you could merge that into later development history (say, v2.6.14-rc5) if you wanted to.
If Linus does something like the above, the graft probably be better done between the current v2.6.12-rc2 based commit history and the corresponding commit in the history resurrected from BKCVS (torvalds/old-2.6-bkcvs.git). Then you could even base your development on top of v2.4.0 ;-).
Funnily, v2.6.12-rc2 commit in the current history and BKCVS v2.6.12-rc2 commit in the resurrected history have different tree IDs.
I am however not quite sure how useful the above would be, though. EVen between 2.6.11 and 2.6.12-rc2 much have happened, so unless the changes you are making apply to the part that did not change between those two, merge conflict resolution might be quite a chore.
Quoted 6 lines
-
To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html
Thanks for detail explanation.
It is a little bit difficult for me. The result of git log shows that the eldest commit is 1da177e4c3f41524e886b7f1b8a0c1fc7321cac2 which is linux-2.6.12-rc2. Is that means the git repository do not store the history before this tag? Then how can git-read-tree v2.6.11 fetchs the content of v2.6.11?
By the way, How could you find the c39ae07f393806ccf406ef966e9a15afc43cc36a out?
I have followed your instuctions and now have my own 2.6.11 branch(my2.6.11). Should be fine now. Many thanks to all you guys.
Quoted 16 lines · Ben Lau
Quoted 8 lines
Linus or somebody authoritative could do:
$ commit=$(echo v2.6.11 | \ git-commit-tree c39ae07f393806ccf406ef966e9a15afc43cc36a) $ git-tag -s -m 'v2.6.11 canonical "fake" commit' v2.6.11fake $commitand tell everybody interested to have:
Quoted 8 lines
1da177e4c3f41524e886b7f1b8a0c1fc7321cac2xxxxxxxxxx(where xxxxx... is the value of $commit above) in their info/grafts file. Then we *could* pretend that v2.6.12-rc2's parent is v2.6.11. You could branch off from v2.6.11fake commit and base your development, and later you could merge that into later development history (say, v2.6.14-rc5) if you wanted to.
Quoted 6 lines
Thanks for detail explanation.
It is a little bit difficult for me. The result of
git logshows that the eldest commit is1da177e4c3f41524e886b7f1b8a0c1fc7321cac2which is linux-2.6.12-rc2. Is that means the git repository do not store the history before this tag?
Linux development on git, at least the history available officially, starts from 2.6.12-rc2.
Let's try to find things together. In the typescript below, ": siamese;" is my shell prompt $PS1.
First, look at v2.6.12-rc2 object. What type is it?
: siamese; git-cat-file -t v2.6.12-rc2
tagIt is a tag. Let's see what's inside.
: siamese; git-cat-file tag v2.6.12-rc2
object 1da177e4c3f41524e886b7f1b8a0c1fc7321cac2
type commit
tag v2.6.12-rc2
Linux v2.6.12-rc2 release
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.2.4 (GNU/Linux)
iD8DBQBCbW8ZF3YsRnbiHLsRAgFRAKCq/TkuDaEombFABkPqYgGCgWN2lQCcC0qc
wznDbFU45A54dZC8RZ5JxyE=
=ESRP
-----END PGP SIGNATURE-----OK, that points at a commit and object name is 1da177e4c... Let's look at that object. You can abbreviate object name here.
: siamese; git-cat-file commit 1da177e4c
tree 0bba044c4ce775e45a88a51686b5d9f90697ea9d
author Linus Torvalds <[email protected]> 1113690036 -0700 committer Linus Torvalds <[email protected]> 1113690036 -0700
Linux-2.6.12-rc2
Initial git repository build. I'm not bothering with the full history, even though we have it. We can create a separate "historical" git archive of that later if we want to, and in the meantime it's about 3.2GB when imported into git - space that would just make the early git days unnecessarily complicated, when we don't have a lot of good infrastructure for it.
Let it rip!
Notice the top three lines? There is no "parent " line, like recent commits, for example:
: siamese; git-cat-file commit v2.6.13
tree 9b182c47688d261775f8c49e06cb795dfc8931dc
parent 20b1730af3ae05450b0e03f5aed40c4313f65db6
author Linus Torvalds <[email protected]> 1125272461 -0700
committer Linus Torvalds <[email protected]> 1125272461 -0700
Linux v2.6.13What this means is that 2.6.12-rc2 was the big-bang, the beginning of time, as far as the history recorded in git is concerned. There was nothing before that time. On the other hand, v2.6.13 has a "parent " line -- this names another commit, and Linus has some change between that parent commit and v2.6.13.
: siamese; git diff v2.6.13^ v2.6.13
diff --git a/Makefile b/Makefile
index 300f61f..5acd1fc 100644
--- a/Makefile
+++ b/Makefile
@@ -1,7 +1,7 @@
VERSION = 2
PATCHLEVEL = 6
SUBLEVEL = 13
-EXTRAVERSION =-rc7
+EXTRAVERSION =
NAME=Woozy Numbat
# *DOCUMENTATION*Of course, the version number has changed. v2.6.13^ is a short-hand to say "first parent of v2.6.13" (see git-rev-parse documentation).
Quoted 2 lines
Then how can
git-read-tree v2.6.11fetchs the content of v2.6.11?
Trees do not have their position in timeline. Only commits do. This is explained by King Penguin himself. If you are reading the documentation on the web,
http://www.kernel.org/pub/software/scm/git/docs/
find the link "The [Discussion] section below contains much useful information...", and follow it. README in the git source tree at the top level has the same. The description there covers the object database and blob/tree/commit/tag objects, and how these things fit together.
Think of a tree as if you created a tar archive (but without even timestamps) of an extracted kernel source tree. It is a snapshot of directory structure and file contents. You can have many such snapshots, but they themselves do not describe how each of them is related with other snapshots. Commit objects tie them together and give them their position in time. The "parent " line above refers to another commit (note that you can have more than one "parent " lines to denote a merge).
Quoted 2 lines
By the way, How could you find the
c39ae07f393806ccf406ef966e9a15afc43cc36aout?
: siamese; git-cat-file tag v2.6.11-tree
object c39ae07f393806ccf406ef966e9a15afc43cc36a
type tree
tag v2.6.11-tree
This is the 2.6.11 tree object.
NOTE! There's no commit for this, since it happened before I started with git.
Eventually we'll import some sort of history, and that should tie this tree
object up to a real commit. In the meantime, this acts as an anchor point for
doing diffs etc under git.
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.2.4 (GNU/Linux)
iD8DBQBCeV/eF3YsRnbiHLsRAl+SAKCVp8lVXwpUhMEvy8N5jVBd16UCmACeOtP6
KLMHist5yj0sw1E4hDTyQa0=
=/bIK
-----END PGP SIGNATURE-----When v2.6.11 was released, there was no git. Linus can create a tree out of that release, and that is what he did.
He could have created a commit that claimed it was the beginning of time. He did not do that because what he could not do was to retroactively make that commit a parent of the v2.6.12-rc2 commit he already made.
This is because any git object (any type) has a name based on a cryptographically secure hash of its contents, and "the contents" in the case of a commit object includes those header lines (which tree object that commit records, what commits its parents are, who wrote it and who committed it when).
Retroactively adding/modifying parent to an existing commit would mean you would change its contents -- hence its name. An existing child of that commit now needs to get its "parent " line changed to point at the updated parent. Which means rewriting the whole history since v2.6.12-rc2 commit.
The "graft" facility I mentioned in my previous message was invented much later. It lets you pretend that a given commit object has an arbitrary set of commit objects as its parents, which is typically different from its real parents. By using it, you *could* pretend that v2.6.12-rc2 is a child of v2.6.11fake commit (which you create by wrapping the v2.6.11 tree into it).
There is a mention on "graft" facility in the repository layout documentation:
http://www.kernel.org/pub/software/scm/git/docs/repository-layout.html
we might want to also refer to this from git-log documentation, and perhaps git-merge-base documentation.