Remote Branch (branch) is the index of a branch in a remote repository. They are local branches that cannot be moved, and are only updated when Git is interacting with the network. The remote branch is like a bookmark that reminds you of the location of the previous branch when you connected to the remote repository.
We (远程仓库名)/(分支名)
represent the remote branch in this form . For example, if we want to look at the last time we were origin
communicating with the warehouse, we should look at master
the origin/master
branch. If you fix a problem with your partner, but they first push a iss53
branch to the remote repository, although you may also have a local iss53
branch, the most recent update to the server should be a origin/iss53
branch.
May be a bit messy, we might as well illustrate. Let's say your team has an address for a git.ourcompany.com
Git server. If you clone from here, Git will automatically name the remote repository for you, origin
download all of the data, create a pointer to its master
branch , name it origin/master
locally , but you can't change its data locally . Then Git builds a local branch of your own, starting with the master
origin
master
same location on the branch where you can start working (see Figure 3-22):
Figure 3-22.Once
a git clone builds your own
local branch master and Remote Branch Origin/master, which point to the last commit of the Origin/master branch .
If you make some changes to your local branch, while master
others git.ourcompany.com
push their updates, the branch on the server master
will move forward, and at the same time your local commit history is moving in a different direction. But as long as you don't communicate with the server origin/master
, your pointer still stays in place and won't move ( see figure 3-23).
Figure 3-23. When you work locally, someone pushes content to the remote repository and the commit history begins to diverge.
you can run git fetch origin
to synchronize the data on the remote server to local. The command first finds the origin
server (in this case git.ourcompany.com
), gets the data you don't have, updates your local database, and moves origin/master
the pointer to its newest location ( See figure 3-24).
Figure 3-24.
The git fetch command updates the remote index。
To demonstrate how a project with multiple remote branches (on different remote servers) works, let's say you have another internal server that is only available to your Agile development team git.team1.ourcompany.com
. It can be git remote add
added as one of the remote branches of the current project with the commands mentioned in Chapter two. We'll name it to teamone
replace the original Git address (see Figure 3-25).
Figure 3-25. Add another server as a remote repository
Now you can use it git fetch teamone
to get the data you don't have on the team server. Because the current content on the server is a origin
subset of your server, Git does not download any data, but simply creates a teamone/master
branch that is named, pointing to teamone
master
the Commit object on the server where the branch is located 31b8e
(see Figure 3-26).
Figure 3-26. You have a local index that points to the master branch on the Teamone server.Push push Local branch
To share a local branch with someone else, you need to push it to a remote repository that you have permission to write to. Your local branch will not be automatically synced to the remote server you are introducing unless you explicitly perform a push operation. In other words, for a branch that has no intention of sharing, you can keep it as a private branch instead of just pushing the feature branches that work together.
If you have a called serverfix
branch that needs to be developed with others , you can run git push (远程仓库名) (分支名)
:
git push origin serverfixCounting objects: 20, done.Compressing objects: 100% (14/14), done.Writing objects: 100% (15/15), 1.74 KiB, done.Total 15 (delta 5), reused 0 (delta 0)To [email protected]:schacon/simplegit.git * [new branch] serverfix -> serverfix
It's a bit of a shortcut, actually. Git automatically serverfix
expands the branch name to refs/heads/serverfix:refs/heads/serverfix
mean "take out my local Serverfix branch and push it to the Serverfix branch of the remote repository ." we'll cover some details in the Nineth chapter refs/heads/
, but you can omit it for general use. It can also be run git push origin serverfix:serferfix
to achieve the same effect, which means "upload my local Serverfix branch to the remote repository and still call it the Serverfix branch ". With this syntax, you can push local branches to a different named remote branch: If you want to call a remote branch awesomebranch
, you can use it git push origin serverfix:awesomebranch
to push the data.
Next, when your collaborators get data from the server again, they will get a new remote branch origin/serverfix
:
$ git fetch originremote: Counting objects: 20, done.remote: Compressing objects: 100% (14/14), done.remote: Total 15 (delta 5), reused 0 (delta 0)Unpacking objects: 100% (15/15), done.From [email protected]:schacon/simplegit * [new branch] serverfix -> origin/serverfix
It is important to note that fetch
after the operation has downloaded the new remote branch, you still cannot edit the branch in the remote repository locally. In other words, in this case, you don't have a new serverfix
branch, just a pointer that you can't move origin/serverfix
.
If you want to merge this content into the current branch, git merge origin/serverfix
you can run it . If you want a copy of your own serverfix
to develop, you can differentiate a new branch on the basis of a remote branch:
$ git checkout -b serverfix origin/serverfixBranch serverfix set up to track remote branch refs/remotes/origin/serverfix.Switched to a new branch "serverfix"
This switches to the new serverfix
local branch, which is consistent with the remote branch origin/serverfix
so that you can continue to develop it inside.
Trace Remote Branch
checkout
The local branch from the remote branch, called the _ Trace branch (Tracking branch) _. a Trace branch is a local branch that has direct contact with a remote branch . in the trace branch git push
, Git will self-infer which branch of the server to which the data should be pushed . In turn, running in these branches git pull
takes all the remote indexes and merges their data into the local branch .
when you clone a warehouse, Git typically automatically creates a branch that is called master
to track origin/master
. That's git push
git pull
why it works right from the start. Of course, you can set as many other tracking branches as you want, such as other branches that are not in the same way origin
master
. Just now we have seen an example of this: git checkout -b [分支名] [远程名]/[分支名]
. If you have 1.6.2 or more versions of Git, you can also use --track
options to simplify :
$ git checkout --track origin/serverfixBranch serverfix set up to track remote branch refs/remotes/origin/serverfix.Switched to a new branch "serverfix"
To set the local branch to a different name than the remote branch, just change the name in the previous version of the command:
$ git checkout -b sf origin/serverfixBranch sf set up to track remote branch refs/remotes/origin/serverfix.Switched to a new branch "sf"
Now your local branch sf
will automatically origin/serverfix
push and crawl the data.
Delete remoteBranch
If you no longer need a remote branch, such as taking a feature and merging it into a remote master
branch (or any other place where the stable code is stored), you can delete it using this very unreasonable syntax: git push [远程名] :[分支名]
. If you want to delete a branch on the server serverfix
instead of deleting commit, run the following command:
git push origin :serverfixTo [email protected]:schacon/simplegit.git - [deleted] serverfix
Boom! The branch on the server is gone. You'd better pay special attention to this page, because you will definitely use that command, and you will probably forget its syntax. There is a convenient way to memorize this command: Remember the grammar we have seen so long ago git push [远程名] [本地分支]:[远程分支]
, if omitted [本地分支]
, it would be tantamount to saying "extract the blanks here and turn it into [远程分支]
".
The branch's rebase
There are two ways to integrate one branch into another: merge
and rebase
rebase
The translation is tentatively "Yan-hop", as you know. )。 In this chapter we will learn what is the rebase, how to use the rebase, why the rebase operation is so charismatic, and under what circumstances we should use the rebase.
Basic rebase operation
Review the previous section on merging (see Figure 3-27), and you'll see that the development process is forked to two different branches and the updates are submitted separately.
Figure 3-27. The commit history of the original fork.
As previously described, the easiest way to integrate a branch is a merge
command that will merge the latest snapshots of the two branches (C3 and C4) and the most recent common ancestor (C2), resulting in a new commit object (C5). 3-28 is shown below:
Figure 3-28. Consolidate a forked history by merging a branch.
In fact, there is another option: You can C3 the changes produced in the C4 on the basis of a re-play. In Git, this operation is called _ rebase _. With the rebase
command, you can move the changes committed in one branch to another branch and replay them again.
In the example above, run:
$ git checkout experiment$ git rebase masterFirst, rewinding head to replay your work on top of it...Applying: added staged command
Its principle is to return to the nearest common ancestor of the two branches, according to the successive commits of the current branch (i.e., the branch to be experiment
C3), to generate a series of file patches, and then to the base branch (that is, the trunk branch master
The last Commit object (C4) is the new starting point, applying the previously prepared patch file, and finally generating a new Merge Commit object (C3 '), which overwrites experiment
the commit history so that it becomes master
the direct downstream of the branch, as shown in 3-29:
Figure 3-29. Repeat the changes made in the C3 to the C4.
Now go back to master
the branch and make a fast-forward merge (see figure 3-30):
Figure 3-30. The fast forward of the master branch.
Now the C3 ' corresponding snapshot, in fact, and the normal three-party merge, that is, the previous example of the C5 corresponding snapshot content is identical. Although there is no difference in the results of the final integration, the rebase can produce a cleaner commit history. If you inspect the history of a branched branch, it will look clearer: as if all the changes were made on a single line, even though they were actually parallel at the same time .
In general, the purpose of our use is to get a patch that can be used cleanly on a remote branch-for example, some projects you're not a maintainer, but if you want to help, it's best to use the rebase: first develop in one of your own branches, and when you're ready to submit patches to the main project, according to the origin/master
latest A rebase operation is then submitted so that the maintainer does not need to do any integration work (in fact, it is the responsibility to resolve the conflict between the branch patch and the latest skeleton code to be resolved by the person who submitted the patch. ), simply make a fast-forward merge based on the warehouse address you provide, or directly accept the patches you submit.
Note that the snapshot pointed to by the last commit in the merge results, whether through a rebase or a tripartite merge, will get the same snapshot content , except that the commit history is different. The rebase repeats the changes in the order in which each line is modified, and the merge is the final result.
Interesting rebase.
The rebase can also be placed in other branches, and not necessarily according to the branch before differentiation. Taking the history of Figure 3-31 as an example, we created the feature branch to add some functionality to the server-side code and server
then submitted C3 and C4. Then add another branch from the C3 place client
to make some corresponding modifications to the client code, so the C8 and C9 are submitted. Finally, it goes back to server
the branch and submits the C10.
Figure 3-31. Separate the history of a feature branch from an attribute branch.
Let's say that in the next software release, we decided to put the client's modifications into the main line and defer the changes to the server-side software (because further testing is required). At this point, we can change the server
branch-based rather than master
the branch (that is, C8 and C9), skip server
directly to the master
branch and repeat it again, but this requires git rebase
the option to specify the --onto
new base branch master
:
$ git rebase --onto master server client
It's like saying, "Take out the client
branches, find the client
server
changes after the common ancestor of the branches and branches, and then master
repeat them again". Isn't it a little complicated? But it turns out to be very cool with the results of 3-32, although client
C8, C9 in the C3, but this only indicates the time of the order, rather than on the basis of the C3 modification, because the server
client
code corresponding to these two branches should be two sets of files, although that is not Very strict, but it should be understood that after the C3 point in time, the other files made c8,c9 changes, put in the trunk replay. ):
Figure 3-32. The other branch of an attribute on an attribute branch is derived from another.
Now it's fast master
-forward to the branch (see Figure 3-33):
$ git checkout master$ git merge client
Figure 3-33. Fast forward to the master branch to include changes to the client branch.
Now we have decided to server
include the changes in the branch. server
master
instead of manually switching to a branch and then performing a rebase operation, we can simply rebase the branch server
-the git rebase [主分支] [特性分支]
command takes the feature branch out and repeats it on server
the master
main branch :
$ git rebase master server
So, server
the progress is applied master
on the basis of 3-34 as shown:
Figure 3-34. Rebase the server branch on the Master branch.
Then you can quickly enter the trunk branch master
:
$ git checkout master$ git merge server
Now client
and server
branching changes have been integrated into the trunk branch, which can be erased. In the end, our commit history will look like Figure 3-35:
$ git branch -d client$ git branch -d server
Figure 3-35. The risk of the eventual submission of historical rebase
Well, the wonderful rebase is not perfect, it has to be followed by a rule:
Once the commit object in the branch is published to the public repository, do not perform a rebase operation on the branch.
If you follow this golden rule, there will be no mistake. Otherwise, the people will hate you, your friends and family will laugh at you, spit you.
At the time of the rebase, we actually discard some existing commit objects and create some similar but different new commit objects . If you publish the Commit object in the original branch, and the others update the download and work on it, and later you git rebase
discard those submissions and post the new commit object, your collaborators will have to re-merge their work. So when you get content from them again, the commit history becomes a mess.
Let's use a practical example to illustrate why public bonding can cause problems. Suppose you cloned from a central server and then made some development on its basis, the commit history looks like Figure 3-36:
Figure 3-36. Clone a warehouse and work on it.
Now, someone has made some changes on the basis of C1 and merged his own branch to get the result C6, pushed to the central server. When you crawl and merge this data into your local development branch, you get the merge result C7, and the history submission becomes Figure 3-37:
Figure 3-37. Grab others to submit and incorporate into your own trunk.
Next, the person pushing the C6 decided to replace the previous merge operation with a rebase, and then to git push --force
get C4 ' by overwriting the history on the server. And then when you download the latest commit from the server, you get:
Figure 3-38. Someone has pushed the C4 ', and discarded the C4 and C6 that you have developed as the basis for development.
You need to merge after downloading the update, but at this point the SHA-1 checksum of the Commit object C4 ' is completely different from the previous C4, so Git will treat them as a new commit object, and in fact your commit history C7 already contain the C4 changes, so the merge operation will C7 and C4 ' Merge to C8 (see Figure 3-39):
Figure 3-39. You merge the same content again, creating a new commit C8.
C8 This step will happen sooner or later, because only then can you stay in sync with the content submitted by other collaborators. After C8, your commit history will contain both C4 and C4 ', which have different SHA-1 checksum values, and if you use git log
view history, you will see that two submissions have the same author date and description, puzzling. What's worse, when you push such a history to the server, it will once again introduce these re-submitted to the central server, further troubling others (in this case, the problem is the responsibility of the release of the C6 and then use the C4 ', the other people will therefore feedback the dual history to the shared backbone, Thus confusing everyone's audiovisual. )。
If you think of a rebase as a means of cleaning up the commit history before push, and just the ones that have not yet been made public, there's no problem . A frustrating problem arises if the submitted objects that have already been exposed have been developed and others have been followed up based on those submissions.
3.7 Summary
Read here, you should have learned how to create a branch and switch to a new branch, convert between different branches, merge local branches, push branches to a shared server, collaborate with others using shared branches, and rebase before sharing.
Git usage explained (10)--remote branch