Git是什么?

Git是世界最先进的分布式版本控制系统之一。

1 安装

[root@localhost ~]# yum -y install git

[root@localhost ~]# git --version

git version 1.7.1


2 版本库操作

创建版本库

版本库又名仓库,英文名repository,可以简单理解为一个目录。这个目录里所有的文件都可以被Git管理起来,并且每个文件的删除、修改Git都能做到跟踪,以便在将来某个时刻进行“还原”。

[root@localhost ~]# mkdir -pv /date/gitdir                 #创建新目录

[root@localhost ~]# cd /date/gitdir/                

[root@localhost gitdir]# git init                          #把当前目录变成Git可以管理的仓库

Initialized empty Git repository in /date/gitdir/.git/

[root@localhost gitdir]# ls -a                             #目录下有.git说明创建成功

.  ..  .git


把文件加入版本库

首先编写文件:

[root@localhost gitdir]# cd /date/gitdir/

[root@localhost gitdir]# vim a.txt

This is a.txt

[root@localhost gitdir]# vim b.txt

This is b.txt

把文件提交到暂存区,使用git add:

[root@localhost gitdir]# git add a.txt

[root@localhost gitdir]# git add b.txt

把文件从暂存区提交到仓库的当前分支(事先必须已提交到暂存区),使用git commit,-m为说明信息:

[root@localhost gitdir]# git commit -m "add 3 files"

[master (root-commit) b9d90d7] add 3 files


现在来修改下文件a.txt

[root@localhost gitdir]# vim a.txt

This is a.txt ,this is not b.txt


使用git status 可以获取当前仓库的状态,下面的命令告诉我们,a.txt被修改过了,但是还没有提交。

[root@localhost gitdir]# git status

# On branch master

# Changed but not updated:

#   (use "git add <file>..." to update what will be committed)

#   (use "git checkout -- <file>..." to discard changes in working directory)

#

#modified:   a.txt

#

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


如果想知道修改的内容,请使用git diff

[root@localhost gitdir]# git diff a.txt

diff --git a/a.txt b/a.txt

index e7a5e02..50fcf2b 100644

--- a/a.txt

+++ b/a.txt

@@ -1,2 +1,2 @@

-This is a.txt

+This is a.txt ,this is not b.txt


再次提交

[root@localhost gitdir]# git add a.txt

[root@localhost gitdir]# git commit -m "add xiugai"

1 files changed, 1 insertions(+), 1 deletions(-)


再查看状态,告诉我们没有要提交的修改:

[root@localhost gitdir]# git status

# On branch master

nothing to commit (working directory clean)


查看提交的历史记录 git log,显示从最近到最远的提交日志。

[root@localhost gitdir]# git log

commit 2ee955e3cd0892fed757bb8f3c1300c04cb92e9e

Author: root <root@localhost.localdomain>

Date:   Mon May 22 18:02:09 2017 +0800


    add xiugai


commit b9d90d7efd809ac61c36539f6266131b7263f036

Author: root <root@localhost.localdomain>

Date:   Mon May 22 17:37:52 2017 +0800


    add 3 files

显示更简明的信息,可以增加下面的参数,前面一大串的字符就是版本号

[root@localhost gitdir]# git log --pretty=oneline

2ee955e3cd0892fed757bb8f3c1300c04cb92e9e add xiugai

b9d90d7efd809ac61c36539f6266131b7263f036 add 3 files


版本回退

再次修改a.txt

[root@localhost gitdir]# vim a.txt

This is a.txt ,this is not b.txt


xiugai


提交

[root@localhost gitdir]# git add a.txt

[root@localhost gitdir]# git commit -m "2 xiugai"

1 files changed, 2 insertions(+), 0 deletions(-)


查看提交的历史记录

[root@localhost gitdir]# git log

commit 8ce2bfbb4db6d8dbbdb3eb2d4a2017296db98096

Author: root <root@localhost.localdomain>

Date:   Tue May 23 19:25:30 2017 +0800


    2 xiugai


commit 2ee955e3cd0892fed757bb8f3c1300c04cb92e9e

Author: root <root@localhost.localdomain>

Date:   Mon May 22 18:02:09 2017 +0800


    add xiugai


commit b9d90d7efd809ac61c36539f6266131b7263f036

Author: root <root@localhost.localdomain>

Date:   Mon May 22 17:37:52 2017 +0800


    add 3 files


版本回退使用命令 git reset,在Git中HEAD 表示当前版本,HEAD^ 表示上一个版本,HEAD^^表示上上个版本,如果往前10个版本则表示为HEAD~10,注意参数--hard

[root@localhost gitdir]# git reset --hard HEAD^

HEAD is now at 2ee955e add xiugai

[root@localhost gitdir]# cat a.txt

This is a.txt ,this is not b.txt


再次查看状态,发现最终修改的版本不见了

[root@localhost gitdir]# git log

commit 2ee955e3cd0892fed757bb8f3c1300c04cb92e9e

Author: root <root@localhost.localdomain>

Date:   Mon May 22 18:02:09 2017 +0800


    add xiugai


commit b9d90d7efd809ac61c36539f6266131b7263f036

Author: root <root@localhost.localdomain>

Date:   Mon May 22 17:37:52 2017 +0800


    add 3 files


如果现在想找回最终修改的版本怎么办呢,看下面的操作,注意版本号可以只写前面几位。

首先查看所有提交的版本号和命令记录,

[root@localhost gitdir]# git reflog

8ce2bfb HEAD@{0}: 8ce2bf: updating HEAD

2ee955e HEAD@{1}: HEAD^: updating HEAD

8ce2bfb HEAD@{2}: commit: 2 xiugai

2ee955e HEAD@{3}: commit: add xiugai

b9d90d7 HEAD@{4}: commit (initial): add 3 files

回到未来的某个版本

[root@localhost gitdir]# git reset --hard 8ce2bfb

HEAD is now at 8ce2bfb 2 xiugai

[root@localhost gitdir]# cat a.txt

This is a.txt ,this is not b.txt


xiugai


工作区和暂存区:

工作区:系统里能看到的目录,如之前创建的目录/gitdir 就是一个工作区。

版本库:工作区里有一个隐藏目录.git,便是Git的版本库。

版本库里有很多东西,其中最重要的就是暂存区(或叫index)。


撤销修改:

撤销修改使用命令git checkout,在这里有两种情况:

1)文件修改后没有放到暂存区,现在撤销修改后就回到和版本库一模一样的状态;

2)文件添加到暂存区后,又做了修改。撤销修改就回到当初添加到暂存区的状态;

修改文件a.txt

[root@localhost gitdir]# vim a.txt

This is a.txt ,this is not b.txt


xiugai

Taday 05/25

文件没有放到暂存区查看仓库当前的状态,Git会提示你提交修改或撤销修改:

[root@localhost gitdir]# git status

# On branch master

# Changed but not updated:

#   (use "git add <file>..." to update what will be committed)

#   (use "git checkout -- <file>..." to discard changes in working directory)

#

#modified:   a.txt

#

# Untracked files:

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

#

#c.txt

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

撤销修改:

[root@localhost gitdir]# git checkout -- a.txt

查看文件:

[root@localhost gitdir]# cat a.txt

This is a.txt ,this is not b.txt


xiugai


修改文件a.txt

[root@localhost gitdir]# cat a.txt

This is a.txt ,this is not b.txt


xiugai

05/25

提交到暂存区:

[root@localhost gitdir]# git add a.txt

查看状态,Git会提醒你,使用命令 git reset HEAD 把暂存区文件a.txt重新放回到工作区:

[root@localhost gitdir]# git status

# On branch master

# Changes to be committed:

#   (use "git reset HEAD <file>..." to unstage)

#

#modified:   a.txt

#

# Untracked files:

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

#

#c.txt

[root@localhost gitdir]# git reset HEAD a.txt

Unstaged changes after reset:

Ma.txt

在工作区撤销修改:

[root@localhost gitdir]# git checkout -- a.txt

[root@localhost gitdir]# cat a.txt

This is a.txt ,this is not b.txt


xiugai


删除文件:

首先创建文件

[root@localhost gitdir]# vim d.txt

This is d.txt

然后提交

[root@localhost gitdir]# git add d.txt

[root@localhost gitdir]# git commit -m "add d.txt"

 1 files changed, 1 insertions(+), 0 deletions(-)

 create mode 100644 d.txt

如果要删除此文件,直接使用rm命令,

[root@localhost gitdir]# rm d.txt

走到这一步,有两个选择,

1)删错了,对其进行还原,其实是把版本库的版本复制到工作区

[root@localhost gitdir]# git checkout -- d.txt

[root@localhost gitdir]# ls

a.txt  b.txt  c.txt  d.txt


2)确定要删除此文件,使用git rm 命令,然后git commit

[root@localhost gitdir]# git rm d.txt

rm 'd.txt'

[root@localhost gitdir]# git commit -m "remove d.txt"

...

delete mode 100644 d.txt


3 远程仓库,GitHub网站是提供Git仓库托管服务的,所以只要注册一个账号,就可以获得一个免费的Git远程仓库。这个仓库任何人都可以看到但只有自己可以修改。

1)在https://github.com/注册账号,建立仓库,并设置SSH服务。

账号注册(略)

设置SSH服务,首先生成密钥对:

[root@localhost ~]# ssh-keygen -t rsa -C "youremail@qq.com"

然后登陆GitHub,打开“Account settings”,“SSH Keys”页面:然后,点“Add SSH Key”,填上任意Title,在Key文本框里粘贴id_rsa.pub文件的内容:


2)关联远程仓库,远程库的名字就是origin,这是Git默认的叫法,也可以改成别的。

[root@localhost gitdir]# git remote add origin https://github.com/zen9/test.git

把本地库的内容推送到远程库上,master为当前分支,-u参数会把本地master分支和远程仓库的master分支关联起来。

[root@localhost gitdir]# git push -u origin master

从现在起,只要本地库提交了修改,就可以通过下面的命令把修改推送至GitHub。注意,第一次推送时需要使用-u的参数。

[root@localhost gitdir]# git push origin master


从远程库克隆

从远程库克隆到本地

[root@localhost gitdir]# git clone git@github.com:z949/test.git


4 分支管理

创建和合并分支:

在Git中,master分支为主分支,我们可以建立新的分支,

创建dev分支,并切换到dev分支,git checkout命令加上-b参数表示创建并切换

[root@localhost gitdir]# git checkout -b dev

DREADME.md

Da.txt

Db.txt

Dd.txt

De.txt

Switched to a new branch 'dev'


查看当前分支:

[root@localhost gitdir]# git branch

* dev

备注:创建和切换分支也可以通过以下命令实现:

[root@localhost gitdir]# git branch zwj

[root@localhost gitdir]# git checkout zwj

[root@localhost gitdir]# git branch

  dev

  master

* zwj



在zwj分支下(当前分支)编辑f.txt文件:

[root@localhost gitdir]# cat f.txt

This is f.txt

然后提交:

[root@localhost gitdir]# git add f.txt

[root@localhost gitdir]# git commit -m "add f.txt"

[zwj 23ee86c] add f.txt

切换到master分支:

[root@localhost gitdir]# git checkout master

Switched to branch 'master'

在master分支上发现没有f.txt文件,因为之前的提交是在zwj分支上

[root@localhost gitdir]# ls

a.txt  b.txt  d.txt  e.txt  README.md  test

现在,把zwj分支上的工作成果合并到master分支(当前分支)上,命令 git merge 用于合并指定分支到当前分支。

[root@localhost gitdir]# git merge zwj

Updating 6daf74a..23ee86c

Fast-forward

 README.md |    2 --

 a.txt     |    5 +----

 b.txt     |    1 -

 d.txt     |    1 -

 f.txt     |    1 +

 5 files changed, 2 insertions(+), 8 deletions(-)

现在可以查看f.txt文件了,和zwj分支提交的完全一样:

[root@localhost gitdir]# cat f.txt

This is f.txt

合并完成后,可以删除zwj分支了:

[root@localhost gitdir]# git branch -d zwj

Deleted branch zwj (was 23ee86c).

[root@localhost gitdir]# git branch

  dev

* master


解决冲突

新建test1分支:

[root@localhost gitdir]# git checkout -b test1

Switched to a new branch 'test1'

修改文件a.txt:

[root@localhost gitdir]# vim a.txt

This is a.txt and date is 04

在test1分支中提交:

[root@localhost gitdir]# git add a.txt

[root@localhost gitdir]# git commit -m "add a.txt"

[test1 3d8b8bd] add a.txt

切换到master分支:

[root@localhost gitdir]# git checkout master

Already on 'master'

Your branch is ahead of 'origin/master' by 2 commits.

然后修改a.txt

[root@localhost gitdir]# vim a.txt

This is a.txt and date 100

提交:

[root@localhost gitdir]# git add a.txt

[root@localhost gitdir]# git commit -m "add a a.txt"

[master 01f6560] add a a.txt

尝试合并到分支test1,发现存在冲突(因为修改的是同一文件的同一行)

[root@localhost gitdir]# git merge test1

Auto-merging a.txt

CONFLICT (content): Merge conflict in a.txt

Automatic merge failed; fix conflicts and then commit the result.

命令git status 也可以告诉我们冲突的文件 :

[root@localhost gitdir]# git status

# On branch master

# Your branch is ahead of 'origin/master' by 3 commits.

#

# Unmerged paths:

#   (use "git add/rm <file>..." as appropriate to mark resolution)

#

#both modified:      a.txt

#

# Untracked files:

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

#

#test/

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

或者直接查看a.txt文件:

[root@localhost gitdir]# cat a.txt

<<<<<<< HEAD

This is a.txt and date 100

=======

This is a.txt and date is 04

>>>>>>> test1

对a.txt作出如下修改:

[root@localhost gitdir]# vim a.txt

This is a.txt and date is 04

再次提交:

[root@localhost gitdir]# git add a.txt

[root@localhost gitdir]# git commit -m "2017 a.txt"

使用以下命令查看分支合并的情况:

[root@localhost gitdir]# git log --graph --pretty=oneline --abbrev-commit

*   c13503d 2017 a.txt

|\  

| * 3d8b8bd add a.txt

* | 01f6560 add a a.txt

|/  

* 23ee86c add f.txt

* 78db2d8 add a.txt

* 6daf74a add e.txt

*   c45d7c8 Merge branch 'master' of github.com:zengwj1949/MyRepository

|\  

| * 4d2d8fb Initial commit

* 4cd4265 add d.txt

* 8ce2bfb 2 xiugai

* 2ee955e add xiugai

* b9d90d7 add 3 files

最后,删除分支test1:

[root@localhost gitdir]# git branch -d test1

Deleted branch test1 (was 3d8b8bd).

总结:当Git无法自动合并分支时,必须首先解决冲突,然后再提交,合并完成。



未完待续