Reputation: 187
Let's say I made the most recent commit and pushed it to the my private repository, how do you go back to the branch you want to checkout and then push it to the head/master of the repository??
git checkout branch_name
and what command do I have to do to move that branch_name to the master/head ?
Upvotes: 0
Views: 649
Reputation: 488183
Based on this comment:
Okay, so I checkout my_branch, i add the change and commit it and whenever I do git push origin master, it says everything up to date.. How do I make it so whenever I pull it from the other remote computer, the changes I made pulls?
What you need is a good tutorial, really, but unfortunately there are a lot of bad tutorials and not that many good ones. I recommend the Pro Git book. It is a lot to read and digest, though.
For the moment, let's just go through what you have so far and make a few short (I hope) notes on what they do. Let's start by noting that there are at least two repositories involved here, yours—your clone, that you made with git clone
—and the one on some other machine that you access under the name origin
. Pretty much everything you do happens in your clone, except for git push
(package up commits from your clone, deliver them to the remote, and ask the remote to change one of its branch names to point to them), and a bit of git fetch
(we'll get to this in a moment).
First:
git checkout my_branch
This tells Git to look up the name my_branch
, which we can assume here is an existing branch in your repository.
Assuming this succeeds, Git sets HEAD
to point to my_branch
. The name my_branch
points to some particular commit, so diagrammatically, we have:
...(some commits)<-o<-o <-- HEAD->my_branch
where the o
s represent the commits. Each commit points back to its parent commit, and my_branch
points to the tip-most (right-most) such commit. Git can then find all the commits by starting from HEAD
, seeing that it points to my_branch
, seeing where my_branch
points (that tip commit), and then following each commit to its parent.
Next, you add/modify some files, maybe remove a file or two, and eventually commit:
...
git add ...
...
git commit
This makes a new commit. The process of making a new commit works by reading HEAD
as usual, finding that it points to my_branch
, reading my_branch
to find its commit (the current tip of the branch), and then making the new commit out of whatever is in the index/staging area (the stuff you git add
-ed above). As a final step, git adjusts my_branch
to point to the new commit.
Let's draw that diagram again, with the new commit in it. Let's draw the new commit as *
instead of just o
, so that we can easily see which one it is:
...(some commits)<-o<-o<-* <-- HEAD->my_branch
So far so good, but all this is strictly in your own repository, so now we get to your question about git push
. Here, things get a little bit complicated.
You ran this:
git push origin master
but we just said, and drew, above, that HEAD
points to my_branch
and my_branch
points to this new *
commit. Where is master
in all of this?
Well, we didn't draw it earlier, and I don't have your repository so I have to guess. But let me guess that master
points to the o
that used to be the tip of my_branch
. In order to draw this, I can't quite draw arrows any more (they aren't in the character set I have on StackOverflow), so I will just use \
:
...(some commits)<-o<-o <-- master
\
* <-- HEAD->my_branch
This is the same drawing as before, except that (1) I had to use two lines and (2) I added the master
branch to it.
When you run git push origin master
you ask your Git to call up origin
's Git and send it some commit(s), namely any commits you have on master
that they don't have on master
. But you and they have the same commits on master
, so your git says "everything up to date" and stops.
What you have here is a new commit on my_branch
.
(Also, the commit before your new one is on both my_branch
and master
, at least in the drawing I just made. I don't have your repository, so I am just guessing. But it is almost certain that some commits are on both branches. This is something unusual about Git, as compared to other version control systems. It's important later, and something to keep in mind: commits can be on many branches. For now, it's just an oddity.)
So, what can you do to get your new commit onto origin
? One thing you can do is push it under the name my_branch
. If origin
has no branch named my_branch
, this will create it there. If origin
does have a my_branch
, this will attempt to set their my_branch
to point to your new commit *
—after, of course, first delivering that commit. Either way:
git push origin my_branch:my_branch
or:
git push origin -u my_branch:my_branch
will try that request. Their Git can accept or reject the request, and will usually do so on the basis of whether they have a branch named my_branch
(and if so, where it points right now).
Note the repetition in my_branch:my_branch
. The name on the left of the colon :
character is the branch name in your repository, and the name on the right is the one you are asking them—the Git on the remote named origin
—to set. These two names do not have to be the same! If they are the same, you can usually just write it once though, and that's what we saw with git push origin master
. You can do this with my_branch
too. I like to include the colon and destination name, at least with new users, since I think it makes what's happening more obvious.
You can also do any of several other things:
master
(in one of several ways depending on how your repository looks right now); ormaster
; ororigin
) to take your new commit that you have on my_branch
and add it to their master
.The last one is equivalent to doing the first one, then doing git push origin master
.
my_branch
onto (your) master
There are two ways to do this, which can do very different things.
git merge
: this has two main sub-modes. It can do a real merge, or it can do what Git calls a fast-forward, which is actually not a merge at all.
git reset
: this has a lot of sub-modes, and is a very sharp tool that can cause a lot of grief if misused. The mode we will talk about here (but not actually use) is to note that what it does is, in a way, much like the last step git push
asks the remote to do. It tells Git to peel a branch label off of whatever commit it points to now, and instead make it point to some other commit.
Let's look at git reset
first, specifically, the "peel off and replace label" operation. Let's draw that graph yet again, too:
...(some commits)<-o<-o <-- master
\
* <-- HEAD->my_branch
First, we need to make HEAD
point to master
, which we do with git checkout
as usual:
git checkout master
which results in:
...(some commits)<-o<-o <-- HEAD->master
\
* <-- my_branch
Now, suppose we were to run git reset --hard my_branch
(let's not actually do it, just look at what it would do if we ran it). This tells git "peel the current branch label" (read READ
=> it's master
) "off of the o
commit it points to now and make it point to the same commit as my_branch
". That is, if we ran this command, we would get:
...(some commits)<-o<-o
\
* <-- my_branch, HEAD->master
Note that the label is moved, but nothing else has changed—the commits that are in the repository are all still the same.
git merge
Now let's go back to git merge
. Unfortunately, git merge
is a fairly complicated operation when it does a real merge. Fortunately, the first thing git merge
does is to check whether it's a very simple operation.
Assuming the graph we have been drawing all along is accurate, this merge is a simple operation. In particular, my_branch
points to a commit that we can reach by "sliding the label fast forward", against the direction of all the arrows, so that it points to commit *
:
...(some commits)<-o<-o
\
* <-- my_branch, HEAD->master
This, as it turns out, is the same as what git reset
would do, but because git merge
first checks to see if this is a safe thing to do, it's the command we probably wanted to use here.
Let's also look at the case where it is not safe, just for completeness. For instance, suppose we actually have this:
...(some commits)<-o<-o<-o <-- HEAD->master
\
* <-- my_branch
In this case, git merge
will do a real merge, while git reset --hard
would just throw out the final o
commit on master
. We can't slide the label forward, we have to back it up first, so the motion from "where master
is now" to my_branch
is not a fast-forward, and git merge
will do a real merge.
git cherry-pick
Finally, just for completeness, let's look at how to copy the commit.
In general, to copy a commit, we use git cherry-pick
. We first get on the branch we want to copy to, such as master
:
...(some commits)<-o<-o<-o <-- HEAD->master
\
* <-- my_branch
and then run git cherry-pick my_branch
. This finds the commit to which my_branch
points (our *
commit) and makes a copy of it, adding the copy to the current branch (read HEAD
, see master
, current branch is master
, copy gets added to master
). The result looks like this:
...(some commits)<-o<-o<-o<-x <-- HEAD->master
\
* <-- my_branch
where x
is a copy of *
.
In all of these cases, we can now git push origin master
to push the original commit *
or its new copy x
to origin
, and then ask origin
to reset its master
to our new commit.
You mentioned "pulls". I recommend re-learning this as two separate steps, because git pull
is really just these two steps:
git fetch
git merge
(or, usually a better command to use, git rebase
)It's actually the git fetch
step that contacts the remote, origin
in your case, and obtains new stuff from them.
The fetch operation brings over commits they have that you don't (and doesn't bother bringing over commits that they have that you already have). Then—this is where it is not a mirror image of git push
—your git fetch
copies their branch information, but renames it. Their master
becomes your origin/master
; if they have a my_branch
, it becomes your origin/my_branch
.
This renaming step is critical to allowing you to merge (or rebase). If fetching just overwrote your branches, you would lose the work you did making the new commits!
Once the fetch is done, you can then merge-or-rebase your work into/onto the new commits you brought over.
I will leave all of the description of rebasing to other postings (or the Pro Git book), but will add this last bit: besides making it clearer what's happening, the reason to keep git fetch
separate from the second step is that this gives you the chance to decide which step to use.
If you know you will use git rebase
, you can combine the two steps by running git pull --rebase
.
If you know you will run git merge
, you can combine the two steps by running git pull
(with no flag).
But what if you want to look first, and then decide? Then you need to use the two separate steps, and insert the "take a look, then decide" part between those two steps. If you start with git pull
, you cannot do this.
(Once you have used Git for a while, you will probably know which command you will use after git fetch
. It will probably usually be git rebase
, actually—and you can configure Git to use --rebase
automatically. But wait until you have used Git for a while.)
Upvotes: 0
Reputation: 142094
Lets see if i understand you correctly.
If you wish to go back to previous commits you have this answer which explain in details what to do.
How to move HEAD back to a previous location? (Detached head)
If you just want to checkout branch you can simply do:
# checkout the desired branch
git checkout <branch>
If you wish to see all your branches and to checkout one of them:
# Update the repository with the list of all branches and deleted the
# one who were deleted on the remote
git fetch --all --prune
# List all branches in the repository
git branch -a
How to work on several branches simultaneously?
You work simultaneously on more than one branch with the git worktree
command.
git worktree add <new_path>
git worktree
will create 2 separate working folders separated from each other while pointing to the same repository.
This will allow you do to any experintals on the enw worktree without having any effect on the repository itself.
Here is a sample on how to create new worktree and what is the result of it:
Upvotes: 0
Reputation: 9546
After commit and push your local changes.use
git fetch
git pull
git checkout {target branch name }
To merge with master
git merge origin / master
Upvotes: 2
Reputation: 1067
The HEAD
should be in your master
branch, and then you have to write:
git merge branch_name
And to go back in your history you should have the hash of the commit you want to go back, and then:
git checkout commit_hash
Here and here you can check the docs for more info.
Upvotes: 0