Git branch-branching principle
The way Git handles branches is incredibly lightweight. Creating a new branch can be done almost instantly, and switching between different branches is just as easy.Unlike many other version control systems, Git encourages frequent branching and merging in your workflow, even many times a day.
first submission
When performing a commit operation, Git will save a commit object.
Suppose there is a working directory that contains three files that will be staged and committed.The staging operation will calculate a checksum for each file (using the SHA-1 hash algorithm), then save a snapshot of the current version of the file to the Git repository (Git uses blob objects to save them), and finally add the checksum to the staging area to wait for submission:
$ git add README test.rb LICENSE
$ git commit -m 'The initial commit of my project'When using git commit for a commit operation, Git will first calculate the checksum of each subdirectory (in this case only the project root directory), and then save these checksums as tree objects in the Git repository.Subsequently, Git will create a commit object, which in addition to the information mentioned above, also contains a pointer to the tree object (the project root directory).This way, Git can reproduce the saved snapshot when needed.
branch operation
View, switch, create and delete branches
git branch -r # 查看远程分支
git branch <new_branch> # 创建新的分支
git branch -v # 查看各个分支最后提交信息
git branch --merged # 查看已经被合并到当前分支的分支
git branch --no-merged # 查看尚未被合并到当前分支的分支
git checkout <branch> # 切换到某个分支
git checkout -b <new_branch> # 创建新的分支,并且切换过去
git checkout -b <new_branch> <branch> # 基于branch创建新的new_branch
git checkout $id # 把某次历史提交记录checkout出来,但无分支信息,切换到其他分支会自动删除
git checkout $id -b <new_branch> # 把某次历史提交记录checkout出来,创建成一个分支
git branch -d <branch> # 删除某个分支
git branch -D <branch> # 强制删除某个分支 (未被合并的分支被删除的时候需要强制)
git branch -m oldname newname 改变当前分支名字,在当前分支下
git branch -m newname 修改当前的分支,在master分支下Branch merging and rebase
git merge <branch> # 将branch分支合并到当前分支 意思就是master主干上,合并新的分支。后多出来一个版本。多跟线合并到一起
git merge origin/master --no-ff # 不要Fast-Foward合并,这样可以生成merge提交
git rebase master <branch> # 将master rebase到branch,合并成一根线,不会出现merge到一起的版本。相当于:
git checkout <branch> && git rebase master && git checkout master && git merge <branch>If you only want a part of the commit content of a certain branch, you can use cherry-pick.First, you need to go to the merged branch and check git log to get the version number you want to merge, and copy it.Then switch to the main branch for pick merge
git checkout dev
git log # 复制一下需要合并的版本号
git checkout master # 切换到master
git cherry-pick f9f3f0a1169 ## f9f3f0a1169为刚才复制的版本号If you want to merge a file or folder on a branch
# 1. 先切换到目标分支
git checkout master
# 2. 使用git checkout命令来检出分支A的指定文件夹
git checkout branchA -- path/to/folder
# 3. 使用git add命令将更改添加到暂存区
git add path/to/folder
# 4. 提交合并结果
git commit -m "Merge folder from branchA into master"Create a branch
How does Git create a new branch?very simple, it Just creates a new pointer for you that can be moved .For example, to create a testing branch, you would use git branch Command:
$ git branch testingPointer to the current branch
There is a * in front of the branch to indicate the current branch.
git branchView the details of the current branch
You can simply use the git log command to see what each branch currently refers to.The parameter that provides this functionality is --decorate.
$ git log --oneline --decorate
f30ab (HEAD -> master, testing) add feature # f30ab提交对象 (HEAD当前所在分支 -> master分支,testing 分支)
34ac2 Fixed bug # 34ac2 提交对象
98ca9 The initial commit of my project # 98ca9 提交对象As you can see, both the current master and testing branches point to commits whose checksums start with f30ab.
Branch switching
$ git checkout testing # git checkout <分支名>So, what benefits will such an implementation bring to us?You might as well submit it again now:
$ vim test.rb
$ git commit -a -m 'made a change'Let’s switch back to the master branch and take a look:
$ git checkout masterthis command did two things 。 One is to make HEAD point back to master branch, the second is to restore the working directory to master The snapshot content pointed to by the branch .That is, if you make changes now, the project will start with an older version.Essentially, this is ignoring testing Modifications made by a branch to facilitate development in another direction.
We might as well make a few more changes and submit:
$ vim test.rb
$ git commit -a -m 'made other changes'Now, the commit history of this project has forked (see Project Fork History).Because you just created a new branch, switched to it to do some work, and then switched back to the master branch to do some other work.The two changes above are for different branches: you can constantly switch and work back and forth between the different branches and merge them when the time comes.And for all of this to work, the only commands you need are branch, checkout and commit.
You can simply use the git log command to view the fork history.Run git log --oneline --decorate --graph --all and it will output your submission history, the pointers to each branch, and the project's branch forks.
$ git log --oneline --decorate --graph --all
* c2b9e (HEAD, master) made other changes
| * 87ab2 (testing) made a change
|/
* f30ab add feature
* 34ac2 fixed bug
* 98ca9 initial commit of my projectBecause a Git branch is essentially just a file containing a checksum of the referent object (a string of length 40 SHA-1 values), it is incredibly efficient to create and destroy.Creating a new branch is equivalent to writing 41 bytes (40 characters and 1 newline) to a file. Can it be so simple but not faster?
This is in sharp contrast to most version control systems of the past, which copied all project files and saved them to a specific directory when creating a branch.Completing this tedious process usually takes several seconds, sometimes even several minutes.The length of time required depends entirely on the size of the project.In Git, projects of any size can create new branches in an instant.At the same time, since the parent object is recorded for each commit, finding the appropriate merge base (annotation: common ancestor) is equally simple and efficient.These efficient features allow Git to encourage developers to create and use branches frequently.
Create branches and switch at the same time
Usually we will switch to a new branch immediately after creating it. You can use the following command:
git checkout -b <newbranchname>Git remote branch management
git pull # 抓取远程仓库所有分支更新并合并到本地
git pull --no-ff # 抓取远程仓库所有分支更新并合并到本地,不要快进合并
git fetch origin # 抓取远程仓库更新
git merge origin/master # 将远程主分支合并到本地当前分支
git checkout --track origin/branch # 跟踪某个远程分支创建相应的本地分支
git checkout -b <local_branch> origin/<remote_branch> # 基于远程分支创建本地分支,功能同上
git push # push所有分支
git push origin master # 将本地主分支推到远程主分支
git push -u origin master # 将本地主分支推到远程(如无远程主分支则创建,用于初始化远程仓库)
git push origin <local_branch> # 创建远程分支, origin是远程仓库名
git push origin <local_branch>:<remote_branch> # 创建远程分支
git push origin -d :<remote_branch> #删除远程分支
git branch -D <branch> 删除本地分支Basic branch management
#创建一个分支
git branch dev
#切换工作目录到dev
git chekcout dev
#将上面的命令合在一起,创建dev分支并切换到dev
git chekcout –b dev
#合并dev分支,当前工作目录为master
git merge dev
#合并完成后,没有出现冲突,删除dev分支
git branch –d dev
#拉去远程仓库的数据,语法为 git fetch [remote-name]
git fetch
#fetch 会拉去最新的远程仓库数据,但不会自动到当前目录下,要自动合并
git pull
#查看远程仓库的信息
git remote show origin
#建立本地的dev分支追踪远程仓库的develop分支
git checkout –b dev origin/develop