入门Git指令

安装sudo apt-get install git 

一、版本库

1.创建版本库

x@ubuntu:~$ mkdir test
x@ubuntu:~$ cd test
 x@ubuntu:~/test$ pwd
/home/x/test
x@ubuntu:~/test$ git init
Initialized empty Git repository in /home/x/test/.git/

2.添加文件test.txt到仓库:

x@ubuntu:~/test$ touch test.txt

x@ubuntu:~/test$ git add test.txt
x@ubuntu:~/test$ git commit -m "push test.txt"
[master (root-commit) c4186e0] push test.txt
1 file changed, 0 insertions(+), 0 deletions(-)

create mode 100644 test.txt

总结:
初始化一个Git仓库,使用git init命令。
添加文件到Git仓库,分两步:
使用命令git add <file>,可反复多次使用,添加多个文件;
使用命令git commit -m "<message>",可以一次提交多个文件。


二、仓库回退机制

1.版本回退:

我们进行以下操作:x@ubuntu:~/test$ git add test.txt
                              x@ubuntu:~/test$ git commit -m "hello world"
                              [master dc571f2] hello world
                              1 file changed, 2 insertions(+)
                              x@ubuntu:~/test$ git add test.txt
                              x@ubuntu:~/test$ git commit -m "welcome github"
                              [master e05767d] welcome github
                              1 file changed, 1 insertion(+)

我们对文件进行两次修改,然后提交修改到版本库里,一共三个版本被提交到版本库里面。

可以使用git log命令进行查看:

x@ubuntu:~/test$ git log
commit e05767da44180ac33d37b7220068fc9a807c2b44
Author: zhangxh <1135978169@qq.com>
Date:   Mon May 21 19:55:18 2018 -0700

    welcome github

commit dc571f2c51f11e10176c67966375eae7adefb73a
Author: zhangxh <1135978169@qq.com>
Date:   Mon May 21 19:54:22 2018 -0700


    hello world

commit c4186e0d24f7db6af6f7343f8151ce546e9a94aa
Author: zhangxh <1135978169@qq.com>
Date:   Mon May 21 19:33:21 2018 -0700

    push test.txt

如果觉得信息过多可以利用git log --pretty=oneline

x@ubuntu:~/test$ git log --pretty=oneline
e05767da44180ac33d37b7220068fc9a807c2b44 welcome github
dc571f2c51f11e10176c67966375eae7adefb73a hello world
c4186e0d24f7db6af6f7343f8151ce546e9a94aa push test.txt

前面的那一串字符是commit id即版本号。

在Git中,用HEAD表示当前版本,也就是最新的提交的e05767da44180ac33d37b7220068fc9a807c2b44(版本号)上一个版本就是HEAD^,上上一个版本就是HEAD^^,当然往上99个版本写成HEAD~99

现在我们要把test.txt回退到上一个版本,也就是hello world那个版本。

利用git reset命令:x@ubuntu:~/test$ git reset --hard HEAD^
                              HEAD is now at dc571f2 hello world

利用cat命令查看是否成功:x@ubuntu:~/test$ cat test.txt

                                          hello world

再利用git log查看版本库的状态:x@ubuntu:~/test$ git log
                                                   commit dc571f2c51f11e10176c67966375eae7adefb73a
                                                   Author: zhangxh <1135978169@qq.com>
                                                   Date:   Mon May 21 19:54:22 2018 -0700

                                                               hello world

                                                   commit c4186e0d24f7db6af6f7343f8151ce546e9a94aa
                                                   Author: zhangxh <1135978169@qq.com>
                                                   Date:   Mon May 21 19:33:21 2018 -0700


                                                               push test.txt

我们可以发现那个welcome github的版本已经不见了,成功回退到上一个版本。

当然,如果你还想要回到welcome github那个版本,我们可以找到刚才welcome github的那个版本号,

再次利用git resetx@ubuntu:~/test$ git reset --hard e05767da44180ac33d37b7220068fc9a807c2b44
                              HEAD is now at e05767d welcome github
                              x@ubuntu:~/test$ cat test.txt
                              hello world

                              welcome github

成功找回那个版本,当然我们版本号可以不用写全,比如写e05767d就可以了,git会自动寻找。

Git提供了一个命令git reflog用来记录你的每一次命令:

x@ubuntu:~/test$ git reflog
e05767d HEAD@{0}: reset: moving to e05767da44180ac33d37b7220068fc9a807c2b44
dc571f2 HEAD@{1}: reset: moving to HEAD^
e05767d HEAD@{2}: commit: welcome github
dc571f2 HEAD@{3}: commit: hello world

c4186e0 HEAD@{4}: commit (initial): push test.txt

可以看到每个版本号。

总结:
HEAD指向的版本就是当前版本,因此,Git允许我们在版本的历史之间随意切换,使用命令git reset --hard commit_id。
穿梭前,用git log可以查看提交历史,以便确定要回退到哪个版本。
要重返未来,用git reflog查看命令历史,以便确定要回到未来的哪个版本。


2.工作区和暂存区

Ubuntu的目录就是一个工作区,比如text的文件夹


工作区有一个隐藏目录.git,这个不算工作区,而是Git的版本库。Git的版本库里存了很多东西,其中最重要的就是称为stage(或者叫index)的暂存区,还有Git为我们自动创建的第一个分支master,以及指向master的一个指针叫HEAD。


我们把文件往Git版本库里添加的时候,是分两步执行的:
第一步是用git add把文件添加进去,实际上就是把文件修改添加到暂存区
第二步是用git commit提交更改,实际上就是把暂存区的所有内容提交到当前分支
因为我们创建Git版本库时,Git自动为我们创建了唯一一个master分支,所以,现在,git commit就是往master分支上提交更改。
可以简单理解为,需要提交的文件修改通通放到暂存区,然后一次性提交暂存区的所有修改

我们在工作区添加一个test2.txt文件,可以利用git status来查看状态:

x@ubuntu:~/test$ touch test2.txt
x@ubuntu:~/test$ git status
On branch master
Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git checkout -- <file>..." to discard changes in working directory)

modified:   test.txt

Untracked files:
  (use "git add <file>..." to include in what will be committed)

test2.txt

no changes added to commit (use "git add" and/or "git commit -a")

可以看到test.txt被修改了,而test2.txt还从来没有被添加过,所以它的状态是Untracked。

使用两次命令git add,把test.txt和test2.txt都添加后,用git status再查看一下:

x@ubuntu:~/test$ git add test.txt
x@ubuntu:~/test$ git add test2.txt
x@ubuntu:~/test$ git status
On branch master
Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)

modified:   test.txt
modified:   test2.txt

总结:
git add命令实际上就是把要提交的所有修改放到暂存区(Stage),然后,执行git commit就可以一次性把暂存区的所有修改提交到分支。


3.修改

Git跟踪并管理的是修改,而非文件。

第一步,对test.txt做一个修改,加一行内容:goodbey!

x@ubuntu:~/test$ cat test.txt
hello world
welcome github
goodbey!

第二步,添加到暂存区

x@ubuntu:~/test$ git add test.txt
x@ubuntu:~/test$ git status
On branch master
Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)

modified:   test.txt

第三步,再次修改test.txt文件,加一行内容:nothing to say ,提交到分支,再查看状态

x@ubuntu:~/test$ cat test.txt
hello world
welcome github
goodbey!
nothing to say
x@ubuntu:~/test$ git commit -m "modified"
[master b3fbf64] modified
 1 files changed, 1 insertions(+)
x@ubuntu:~/test$ git status
On branch master
Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git checkout -- <file>..." to discard changes in working directory)

modified:   test.txt

no changes added to commit (use "git add" and/or "git commit -a")

可以发现第二次修改没有被提交,我们的操作是:第一次修改 -> git add -> 第二次修改 -> git commit

Git管理的是修改,当你用git add命令后,在工作区的第一次修改被放入暂存区,准备提交,但是,在工作区的第二次修改并没有放入暂存区,所以,git commit只负责把暂存区的修改提交了,也就是第一次的修改被提交了,第二次的修改不会被提交。

git diff HEAD -- test.txt命令可以查看工作区和版本库里面最新版本的区别:

x@ubuntu:~/test$ git diff HEAD -- test.txt
diff --git a/test.txt b/test.txt
index 00e542d..df32842 100644
--- a/test.txt
+++ b/test.txt

@@ -3,3 +3,5 @@ 

 hello world

 welcome github
 
 goodbey!
+
+nothing to say

可以发现第二次修改并没有被提交。

可以继续git addgit commit,也可以别着急提交第一次修改,先git add第二次修改,再git commit,就相当于把两次修改合并后一块提交了:第一次修改 -> git add -> 第二次修改 -> git add -> git commit

总结:
每次修改,如果不用git add到暂存区,那就不会加入到commit中。


4.撤销修改

<1>你在text.txt加入了一句:it is so hot,但是现在我不想要这一句了。

x@ubuntu:~/test$ git status
On branch master
Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git checkout -- <file>..." to discard changes in working directory)

modified:   test.txt

no changes added to commit (use "git add" and/or "git commit -a")

可以发现,Git提供语句:git checkout -- file可以丢弃工作区的修改

x@ubuntu:~/test$ git checkout -- test.txt
x@ubuntu:~/test$ cat test.txt
hello world
welcome github
goodbey!

可以发现内容it is so hot不见了,撤销成功。

git checkout -- file命令中的--很重要,没有--,就变成了“切换到另一个分支”的命令


<2>你写错了文档,还git add到暂存区了。

x@ubuntu:~/test$ cat test.txt
hello world
welcome github
goodbey!
mistake message
x@ubuntu:~/test$ git add test.txt
x@ubuntu:~/test$ git status
On branch master
Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)
modified:   test.txt

 Git提供命令git reset HEAD <file>可以把暂存区的修改撤销掉(unstage),重新放回工作区。git reset命令既可以回退版本,也可以把暂存区的修改回退到工作区。当我们用HEAD时,表示最新的版本。

x@ubuntu:~/test$ git reset HEAD test.txt
Unstaged changes after reset:
M test.txt

x@ubuntu:~/test$ git status
On branch master
Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git checkout -- <file>..." to discard changes in working directory)

modified:   test.txt

no changes added to commit (use "git add" and/or "git commit -a")

现在暂存区是干净的,工作区有修改,我们可以利用git checkout -- test.txt进行工作区的修改。

x@ubuntu:~/test$ git checkout -- test.txt
x@ubuntu:~/test$ git status
On branch master
nothing to commit, working directory clean

<3>你不但改错了东西,还从暂存区提交到了版本库,这时候可以利用版本回退来撤销修改。

总结:
1:当你改乱了工作区某个文件的内容,想直接丢弃工作区的修改时,用命令git checkout -- file。
2:当你不但改乱了工作区某个文件的内容,还添加到了(add)暂存区时,想丢弃修改,分两步,第一步用命令git reset HEAD <file>,就回到了1,第二步按1操作。
3:已经提交了不合适的修改(commit)到版本库时,想要撤销本次提交,可以利用版本回退(参考前面讲过的版本回退),不过前提是没有推送到远程库。


5.删除文件

在Git中,删除也是一个修改操作

我们删除test2.txt,利用命令rm -r test2.txt,这时候工作区和版本库就不一致了,可以利用git status来查看哪些文件被删除了

x@ubuntu:~/test$ rm -r test2.txt
x@ubuntu:~/test$ git status
On branch master
Changes not staged for commit:
  (use "git add/rm <file>..." to update what will be committed)
  (use "git checkout -- <file>..." to discard changes in working directory)

deleted:    test2.txt

no changes added to commit (use "git add" and/or "git commit -a")

<1>我们误删了文件,这时候可以利用git checkout -- test2.txt来进行恢复

<2>我们确实要从版本库中删除文件,可以用命令git rm删掉,并且git commit:

x@ubuntu:~/test$ git rm test2.txt
rm 'test2.txt'
x@ubuntu:~/test$ git commit -m "delete test2.txt"
[master 024a3bb] delete test2.txt
 1 file changed, 1 deletion(-)
 delete mode 100644 test2.txt

总结:
命令git rm用于删除一个文件。如果一个文件已经被提交到版本库,那么你永远不用担心误删,但是要小心,你只能恢复文件到最新版本,你会丢失最近一次提交后你修改的内容。


三、远程仓库GitHub

1.添加远程库

本地创建了一个Git仓库后,又想在GitHub创建一个Git仓库,并且让这两个仓库进行远程同步,GitHub上的仓库既可以作为备份,又可以让其他人通过该仓库来协作。

1.登陆GitHub,然后,在右上角找到“Create a new repo”按钮,创建一个新的仓库。

2.在Repository name填入test,其他保持默认设置,点击“Create repository”按钮,就成功地创建了一个新的Git仓库。

3.在本地的learngit仓库下运行命令:

$ git remote add origin git@github.com:ZhangCats/test.git

注意,把上面的ZhangCats替换成你自己的GitHub账户名,否则,你在本地关联的就是我的远程库,关联没有问题,但是你以后推送是推不上去的,因为你的SSH Key公钥不在我的账户列表中。

添加后,远程库的名字就是origin,这是Git默认的叫法,也可以改成别的,但是origin这个名字一看就知道是远程库。

把本地库的所有内容推送到远程库上:$ git push -u origin master

x@ubuntu:~/test$ git remote add origin git@github.com:ZhangCats/test.git
x@ubuntu:~/test$ git push -u origin master
To git@github.com:ZhangCats/test.git
 ! [rejected]        master -> master (fetch first)
error: failed to push some refs to 'git@github.com:ZhangCats/test.git'
hint: Updates were rejected because the remote contains work that you do
hint: not have locally. This is usually caused by another repository pushing
hint: to the same ref. You may want to first integrate the remote changes
hint: (e.g., 'git pull ...') before pushing again.
hint: See the 'Note about fast-forwards' in 'git push --help' for details.

此时出了一个错误,原因是本地和远程的master没有同步

我们可以利用git pull --rebase origin master拉取远程的文件把本地的覆盖,再上传

x@ubuntu:~/test$ git pull --rebase origin master
From github.com:ZhangCats/test
 * branch            master     -> FETCH_HEAD
First, rewinding head to replay your work on top of it...
Applying: push test.txt
Applying: hello world
Applying: welcome github
Applying: add test2.txt
Applying: add test.txt
Applying: modified
Applying: delete test2.txt
x@ubuntu:~/test$ git push -u origin master
Counting objects: 20, done.
Compressing objects: 100% (14/14), done.
Writing objects: 100% (20/20), 1.77 KiB | 0 bytes/s, done.
Total 20 (delta 2), reused 0 (delta 0)
remote: Resolving deltas: 100% (2/2), done.
To git@github.com:ZhangCats/test.git
   47f2448..edf384c  master -> master
Branch master set up to track remote branch master from origin.


上传成功。把本地库的内容推送到远程,用git push命令,实际上是把当前分支master推送到远程。
由于远程库是空的,我们第一次推送master分支时,加上了-u参数,Git不但会把本地的master分支内容推送的远程新的master分支,还会把本地的master分支和远程的master分支关联起来,在以后的推送或者拉取时就可以简化命令。

总结:
要关联一个远程库,使用命令git remote add origin git@server-name:path/repo-name.git;
关联后,先用命令git pull --rebase origin master拉取远程文件覆盖本地,再使用命令git push -u origin master第一次推送master分支的所有内容;
此后,每次本地提交后,只要有必要,就可以使用命令git push origin master推送最新修改;


2.远程库克隆

我们从零开发,那么最好的方式是先创建远程库,然后从远程库克隆。我们在github已经有了一个名为test的远程库,我们在Ubuntu本地新建一个名为clonetest的文件夹。然后利用git clone git@github.com:ZhangCats/test.git命令把整个远程库test克隆到本地文件夹下,这时候我们在clonetest文件夹下的test工作区新建一个test3.txt文件,利用git push -u origin master命令把文件上传到远程库。

x@ubuntu:~$ mkdir clonetest
x@ubuntu:~$ cd ~/clonetest
x@ubuntu:~/clonetest$ git clone git@github.com:ZhangCats/test.git
Cloning into 'test'...
remote: Counting objects: 23, done.
remote: Compressing objects: 100% (13/13), done.
Receiving objects: 100% (23/23), done.
Resolving deltas: 100% (2/2), done.
remote: Total 23 (delta 2), reused 20 (delta 2), pack-reused 0
Checking connectivity... done.
x@ubuntu:~/clonetest$ cd ~/clonetest/test
x@ubuntu:~/clonetest/test$ ls -ah
.  ..  .git  README.md  test.txt
x@ubuntu:~/clonetest/test$ touch test3.txt
x@ubuntu:~/clonetest/test$ git add test3.txt
x@ubuntu:~/clonetest/test$ git commit -m "add test3.txt"
[master ade6080] add test3.txt
 1 file changed, 0 insertions(+), 0 deletions(-)
 create mode 100644 test3.txt
x@ubuntu:~/clonetest/test$ git push -u origin master
Counting objects: 3, done.
Compressing objects: 100% (2/2), done.
Writing objects: 100% (3/3), 299 bytes | 0 bytes/s, done.
Total 3 (delta 0), reused 1 (delta 0)
To git@github.com:ZhangCats/test.git
   edf384c..ade6080  master -> master
Branch master set up to track remote branch master from origin.



总结:
要克隆一个仓库,首先必须知道仓库的地址,然后使用git clone命令克隆。
Git支持多种协议,包括https,但通过ssh支持的原生git协议速度最快


3.删除github远程库的一个文件

我们在github网站上不能直接删除一个文件,只能删除一个repository也就是仓库。不顾我们可以在本地工作区先删除文件,然后再同步推给远程库。我们这里把刚才上传的test3.txt在本地库利用git rm -r --cached file命令先删除,然后提交commit修改(因为删除也是一种修改),然后提交个远程库。

x@ubuntu:~/clonetest/test$ git rm -r --cached test3.txt
rm 'test3.txt'
x@ubuntu:~/clonetest/test$ git commit -m "delets test3.txt"
[master 7ec80e8] delets test3.txt
 1 file changed, 0 insertions(+), 0 deletions(-)
 delete mode 100644 test3.txt
x@ubuntu:~/clonetest/test$ git push origin master
Counting objects: 2, done.
Compressing objects: 100% (2/2), done.
Writing objects: 100% (2/2), 218 bytes | 0 bytes/s, done.
Total 2 (delta 1), reused 0 (delta 0)
remote: Resolving deltas: 100% (1/1), completed with 1 local object.
To git@github.com:ZhangCats/test.git
   ade6080..7ec80e8  master -> master


总结:

github不能直接删除一个文件,利用命令git rm -r --cached file命令在本地版本库先删除文件,在推送到远程库。


四、分支管理


1.创建合并分支

在版本回退里,每次提交,Git都把它们串成一条时间线,这条时间线就是一个分支。截止到目前,只有一条时间线,在Git里,这个分支叫主分支,即master分支。HEAD严格来说不是指向提交,而是指向master,master才是指向提交的,所以,HEAD指向的就是当前分支。



每次提交,master分支都会向前移动一步,这样,随着你不断提交,master分支的线也越来越长:



当我们创建新的分支,例如dev时,Git新建了一个指针叫dev,指向master相同的提交,再把HEAD指向dev,就表示当前分支在dev上:



Git创建一个分支很快,因为除了增加一个dev指针,改改HEAD的指向,工作区的文件都没有任何变化!从现在开始,对工作区的修改和提交就是针对dev分支了,比如新提交一次后,dev指针往前移动一步,而master指针不变:



我们在dev上的工作完成了,就可以把dev合并到master上。Git合并最简单的方法,就是直接把master指向dev的当前提交,就完成了合并:



git合并分支很快,就改改指针,工作区内容也不变!合并完分支后,甚至可以删除dev分支。删除dev分支就是把dev指针给删掉,删掉后,我们就剩下了一条master分支:


<1>我们利用命令git checkout -b dev创建分支dev,然后切换到分支devgit checkout命令加上-b参数表示创建并切换,相当于以下两条命令:git branch devgit checkout dev

x@ubuntu:~/test$ git checkout -b dev
Switched to a new branch 'dev'

<2>用git branch命令查看当前分支,git branch命令会列出所有分支,当前分支前面会标一个*号。

x@ubuntu:~/test$ git branch
* dev
  master

<3>我们在dev分支上提交一个test4.txt文档,然后提交。

x@ubuntu:~/test$ touch test4.txt
x@ubuntu:~/test$
cat test4.txt
good time
x@ubuntu:~/test$ git add test4.txt
x@ubuntu:~/test$ git commit -m "add test4.txt"
[dev 57d5464] add test4.txt
 1 file changed, 1 insertion(+)
 create mode 100644 test4.txt

<4>dev分支的工作完成,我们就可以切换回master分支,再查看一个test4.txt文件,刚才添加的内容不见了!因为那个提交是在dev分支上,而master分支此刻的提交点并没有变:

x@ubuntu:~/test$ git checkout master
Switched to branch 'master'
Your branch is up-to-date with 'origin/master'.
x@ubuntu:~/test$ cat test4.txt
cat: test4.txt: No such file or directory

<5>我们把dev分支的工作成果合并到master分支上,git merge <name>命令用于合并指定分支到当前分支。合并后,再查看test4.txt的内容,就可以看到,和dev分支的最新提交是完全一样的。

x@ubuntu:~/test$ git merge dev
Updating edf384c..57d5464
Fast-forward
 test4.txt | 1 +
 1 file changed, 1 insertion(+)
 create mode 100644 test4.txt
x@ubuntu:~/test$ cat test4.txt
good time

注意到上面的Fast-forward信息,Git告诉我们,这次合并是“快进模式”,也就是直接把master指向dev的当前提交,所以合并速度非常快。当然,也不是每次合并都能Fast-forward,我们后面会讲其他方式的合并。

<6>合并完成后就可以利用命令git branch -d dev删除分支dev了,然后再查看下branch,就只剩下master了。

x@ubuntu:~/test$ git branch -d dev
Deleted branch dev (was 57d5464).
x@ubuntu:~/test$ git branch
* master

总结:
查看分支:git branch
创建分支:git branch <name>
切换分支:git checkout <name>
创建+切换分支:git checkout -b <name>
合并某分支到当前分支:git merge <name>
删除分支:git branch -d <name>


2.解决分支冲突

<1>我们创建新的分支dev1,修改test4.txt内容为The Saltwater Room,然后在分支dev1上提交

x@ubuntu:~/test$ cat test4.txt
The Saltwater Room
x@ubuntu:~/test$ git checkout -b dev1
M test4.txt
Switched to a new branch 'dev1'
x@ubuntu:~/test$ git add test4.txt
x@ubuntu:~/test$ git commit -m "add text4.txt to dev1"
[dev1 e3c9977] add text4.txt to dev1
 1 file changed, 1 insertion(+), 1 deletion(-)

<2>切换到master分支,修改test4.txt内容为Owl City,然后提交

x@ubuntu:~/test$ git checkout master
Switched to branch 'master'
Your branch is ahead of 'origin/master' by 1 commit.
  (use "git push" to publish your local commits)
x@ubuntu:~/test$ git add test4.txt
x@ubuntu:~/test$ git commit -m "owl city"
[master f6b8580] owl city
 1 file changed, 1 insertion(+), 1 deletion(-)

Git还会自动提示我们当前master分支比远程的master分支要超前1个提交。

现在,master分支和feature1分支各自都分别有新的提交,变成了这样:


<3>这种情况下,Git无法执行“快速合并”,只能试图把各自的修改合并起来,但这种合并就可能会有冲突

x@ubuntu:~/test$ git merge dev1
Auto-merging test4.txt
CONFLICT (content): Merge conflict in test4.txt
Automatic merge failed; fix conflicts and then commit the result.

<4>Git告诉我们,test4.txt文件存在冲突,必须手动解决冲突后再提交。git status也可以告诉我们冲突的文件:

x@ubuntu:~/test$ git status
On branch master
Your branch is ahead of 'origin/master' by 2 commits.
  (use "git push" to publish your local commits)
You have unmerged paths.
  (fix conflicts and run "git commit")

Unmerged paths:
  (use "git add <file>..." to mark resolution)

both modified:   test4.txt

no changes added to commit (use "git add" and/or "git commit -a")

<5>我们可以直接查看test4.txt内容

x@ubuntu:~/test$ cat test4.txt
<<<<<<< HEAD
Owl City
=======
The Saltwater Room
>>>>>>> dev1

Git用<<<<<<<,=======,>>>>>>>标记出不同分支的内容,我们修改如下后保存:

<6>我们在master下修改test4.txt的内容为The Saltwater City然后合并分支,然后删除分支就可以了。


<7>用带参数的git log --graph --pretty=oneline --abbrev-commit可以看到分支的合并情况,最后删除分支。

x@ubuntu:~/test$ git log --graph --pretty=oneline --abbrev-commit

*    9004808 The Saltwater Room
|  
| * e3c9977 add text4.txt to dev1
*
| f6b8580 owl city
|/   
*
57d5464 add test4.txt
*
edf384c delete test2.txt
*
fc2ddbf modified
*
d6cb3e6 add test.txt
*
17f1f21 add test2.txt
*
a2e3099 welcome github
*
54dbe8e hello world
*
99cd4f7 push test.txt

* 47f2448 Initial commit

x@ubuntu:~/test$ git branch -d dev1
Deleted branch dev1 (was e3c9977).

总结:
当Git无法自动合并分支时,就必须首先解决冲突。解决冲突后,再提交,合并完成。
解决冲突就是把Git合并失败的文件手动编辑为我们希望的内容,再提交。
用git log --graph --pretty=oneline --abbrev-commit命令可以看到分支合并图。


3.分支管理方法

通常合并分支时,Git会用Fast forward模式,但这种模式下,删除分支后,会丢掉分支信息。
如果要强制禁用Fast forward模式,Git就会在merge时生成一个新的commit,这样从分支历史上就可以看出分支信息。
下面我们实现--no-ff方式的git merge:

<1>创建并切换分支dev,修改test4.txt的内容,并提交到分支:

x@ubuntu:~/test$ git checkout -b dev
M test4.txt
Switched to a new branch 'dev'
x@ubuntu:~/test$ cat test4.txt
The Saltwater Room
good song

x@ubuntu:~/test$ git add test4.txt
x@ubuntu:~/test$ git commit -m "modify test4.txt"
[dev 328858b] modify test4.txt
 1 file changed, 1 insertion(+), 4 deletions(-)

<2>切换回master,准备合并dev分支,请注意--no-ff参数,表示禁用Fast forward,因为本次合并要创建一个新的commit,所以加上-m参数,把commit描述写进去。:

x@ubuntu:~/test$ git checkout master
Switched to branch 'master'
Your branch is ahead of 'origin/master' by 4 commits.
  (use "git push" to publish your local commits)
x@ubuntu:~/test$ git merge --no-ff -m "merge with no-ff" dev
Merge made by the 'recursive' strategy.
 test4.txt | 5 +----
 1 file changed, 1 insertion(+), 4 deletions(-)

<3>合并后,我们利用git log --graph --pretty=oneline --abbrev-commit 

x@ubuntu:~/test$ git log --graph --pretty=oneline --abbrev-commit
*   dc2edc1 merge with no-ff
|\  
| * 328858b modify test4.txt
|/  
*   9004808 The Saltwater Room
| 
| * e3c9977 add text4.txt to dev1
* | f6b8580 owl city
|/  
* 57d5464 add test4.txt
* edf384c delete test2.txt
* fc2ddbf modified
* d6cb3e6 add test.txt
* 17f1f21 add test2.txt
* a2e3099 welcome github
* 54dbe8e hello world
* 99cd4f7 push test.txt
* 47f2448 Initial commit

可以看到,不使用Fast forward模式,merge后就像这样:


策略方法:首先,master分支应该是非常稳定的,也就是仅用来发布新版本,平时不能在上面干活。干活都在dev分支上,也就是说,dev分支是不稳定的。到正式版本发布时,再把dev分支合并到master上,在master分支发布正式的版本。每个人都在dev分支上干活,每个人都有自己的分支,时不时地往dev分支上合并就可以了。

总结:
合并分支时,加上--no-ff参数就可以用普通模式合并,合并后的历史有分支,能看出来曾经做过合并,而fast forward合并就看不出来曾经做过合并。









  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值