Okay, I'm not that familiar with Git. I was asked to clone a repository from someone's repository and then use the tag. So here's what I did:
git clone someones_repo my_new_repo
git checkout tags/bla_bla_tag -b tag_branch
So now I'm in the tag version and not in the master branch but in the tag_branch.
I did changes and want to commit them and merge them with my master and then turn in my changes to our official repository (I think they call this golden repo). And here are my worries:
When you create a branch off of a "tag", you create a pointer to a commit. The tag points to a commit and your branch is like a pointer to this commit as well. If this commit is on the master branch or not is impossible to say without more information.
To get the latest master you can do git fetch
and the latest master will be in origin/master
.
For example, if you have created one commit based on the tagged commit, you can deliver it by:
git checkout master
git pull -r
git cherry-pick <your commit>
git push origin master
In plain english this would mean. Checkout local master. Update local master to match remote master. Put your new commit ontop of local master, and update local master to point to this commit. Deliver local master to remote master.
I am not sure what you meant by "turn in the changes to the main repo". I am hoping its a pull request and not a push directly to the golden repo
The master of your local branch will be the same as that of that someone's repo. It may be the same as the master of the golden repo, if those two repos are kept in sync regularly.
A tag is just a label you add to some commit, usually for a commit in master. If your pull request is merged, the master in golden repo will become your version of master. And if someone clones the golden repo they will get your request version.
I would recommend using the pull request workflow for this. Otherwise the chance of losing commits are very high
There are a few good answers already, but what you really could use here is a graphical illustration.
The key to understanding how branches and tags work in Git is to realize that the branch and tag names are mere auxiliaries. They do very little to actually make branches. The very word "branch" itself is actually ambiguous in Git. To see more about this, and several diagrams, click on What exactly do we mean by "branch"? This describes how branch labels select particular commits, although not the process by which a branch grows . (Note also that the first image from the Pro Git book is fine, but like Jubobs, I dislike the second Pro Git image.)
I use a simpler diagramming method in StackOverflow postings. Take this example diagram of a repository with just three commits. Each of these three commits has an actual hash ID—one of those big ugly 40-character things that abbreviate to badf00d
and cafedad
and so on—but I just give them one-letter names, and put the branch name on the right:
A <- B <- C <-- master
Here C
is our latest commit, on branch master
. The branch name master
contains the actual hash ID of commit C
, such as ac0ffee4cafedad5badf00d...
or whatever. Commit C
itself—the actual commit, stored inside Git's database—has in it the ID of commit B
. We say that master
points to C
, and C
points to B
. B
has the ID of A
, so it points to A
. A
was the very first commit anyone ever made, so it cannot point anywhere. It has no parent , in Git's terms; it is a root commit .
Note that in this system, parent commits don't know which children they have, but children do know their parents. To make a new commit on master
, Git writes some things into the database, ending with the new commit object. The new commit—let's call it D
—contains the current commit's ID as its parent, so that D
points back to C
. Then Git updates the branch name , master
, so that it points to D
:
A <- B <- C <- D
(As someone pointed out recently, this is a lot like digging through genealogy records: you find something like "Bob Jones, born to parents Arthur and Sally". Obviously Bob's birth record can't list that 25 years later he will have a daughter, so it just doesn't. Similarly, when you make a commit, Git knows who the commit's parent is, but it has no idea whether the commit will have children.)
With that in mind, consider this graph fragment. I've stopped drawing the internal arrows to save space and such, but remember, they always point backwards (leftwards in these drawings):
...--D--E--F <-- master
\
G--H <-- sidebr
We get here by making two new commits on master
, ie, E
and F
, but also by creating a new branch name , sidebr
, pointing to commit D
. Then we git checkout sidebr
and make two new commits. These are G
and H
. When we make G
, commit D
is current, and is what sidebr
points-to. So Git writes the commit with D
as its parent and changes sidebr
to point to G
. Now that G
is current, we make new commit H
with G
as its parent, and update sidebr
to point to H
, and that's how we got to this diagram.
Now is the time to add tags to these pictures. Tags are almost (but not quite) the same as branches. Like branch names, tag names point to commits. The key difference 1 is that branch names are supposed to move: they grow automatically, by adding new commits. Tag names are not supposed to move.
As a result, we might as well draw them "inside" the commit diagram, rather than way over on the right. (Or, if we had color, we could use different colors for branch and tag names—but I cannot do color in text on StackOverflow.) So let's add a tag name pointing to commit E
:
tag:v0.1
|
v
...--D--E--F <-- master
\
G--H <-- sidebr
This tag points to commit E
. It should always, forever-more, point to commit E
. 2 There's an interesting fact about raw Git hash IDs that is quite relevant here: the hash ID is totally deterministic, and is based entirely upon the actual contents of the commit (or other Git object). Tag names therefore do little more than provide a human-readable name for one of those awful hash IDs. If we could all just remember 17f9f635c101aef03874e1de1d8d0322187494b3
, we would not need the tag v2.6.0
in the Git repository for Git—but I'm certainly not going to remember that. 3
In any case, you can git checkout
any commit by its ID, or by anything that resolves to its ID. A tag name works for the latter, and of course, is much easier to remember. So, given the above diagram, we can check out commit E
with:
git checkout v0.1
(the tag:
is not part of the tag name, just something I wrote to say why we have an arrow here). This, however, gives us a "detached HEAD", so that's why we git checkout -b newbranch v0.1
: that assigns a new branch name to point to the commit. Now we need to re-draw the graph a bit to give more room:
tag:v0.1
|
| F <-- master
v /
...--D--E <-- newbranch (HEAD)
\
G--H <-- sidebr
I also added this HEAD
thing: that's a reminder that we're now on this new branch. If we make a new commit now, this will grow the branch in the usual way:
tag:v0.1
|
| F <-- master
v /
...--D--E--I <-- newbranch (HEAD)
\
G--H <-- sidebr
The tag—which is not supposed to move—does not move. The branch , however, does move. We can make whatever commits we like, and each one makes the current branch— newbranch
—advance to incorporate each of our new commits.
1 Another important difference is that tag names live in a shared name space, across all repositories, while branches don't. There are also annotated tags , which give you the opportunity to attach some uninterpreted data, and Git lets you sign such tags using GPG encryption. But that's for another discussion.
2 It's possible to forcibly move a tag, or to remove it and re-create it pointing to a different commit. Sometimes there is even a good reason to do that. You just need to be sure the reason is especially good, because the tag is really just a human-readable name for the hash ID, and any repository that already has the old tag, is likely to think the old tag-to-hash-ID mapping is still correct, even after you have forcibly moved the tag.
3 I used git rev-parse v2.6.0
to find it. The hash ID above is the ID of the annotated tag object (which you can find by cloning the Git repository for Git). The actual commit is be08dee9738eaaa0423885ed189c2b6ad8368cf0
. There is special syntax for finding the commit ID in one step, using git rev-parse
, or you can use git show v2.6.0
to read the tag object, and then git show
the tag's target object to see the commit, for instance.
For your questions:
git fetch origin git log master..origin/master
If there has output, that means your local master is not the latest version, you should use git pull
to pull changes.
PS: If both you and your colleague are work for official repo, you should clone from official repo at the first.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.