1.Git入门以及安装

1.1 Git简单介绍

Git是一个开源的分布式版本控制系统,用于敏捷高效地处理任何或大或小的项目。

1.2 Git安装

# 在ubuntu系统上进行安装
sudo apt-get install git

2.Git基础使用

2.1 设置用户信息

当安装完成Git后可以设置用户名称和邮件地址。每一次Git的提交都会使用这些信息,并且会写入到每一次提交中,不可更改:

$ git config --global user.name "username"
$ git config --global user.email useremail

如果使用了–global选项,那该命令只需要运行一次,以后无论你在该系统上做任何事情,Git都会使用这些信息。当你想针对特定的项目使用不同的用户名称和邮箱地址时,可以在那个项目目录下运行不使用–global选项的命令来配置

2.2 设置默认的文本编辑器

用户信息已经设置完毕,可以配置默认的文本编辑器,当Git需要你输入信息时会调用它。如果为配置,Git会使用系统默认的文本编辑器,通常为Vim。

$ git config --global core.editor gedit

2.3 检查配置信息

如果要检查你的配置,可以使用git config --list命令来列出所有Git当时能找到的配置

bj@ubuntu:~$ git config --list 
user.email=yangqi199808@yeah.net
user.name=yangqi199808
core.editor=gedit
core.repositoryformatversion=0
core.filemode=true
core.bare=false
core.logallrefupdates=true
...

还可以通过输入git config :来检查Git的某一项配置。

bj@ubuntu:~$ git config user.name 
username
bj@ubuntu:~$ git config user.email 
useremail
bj@ubuntu:~$ 

2.4 获取帮助

在使用Git时需要帮助,可以通过以下三种方法找到Git命令的使用手册:

$ git help <verb>
$ git <verb> --help
$ man git-<verb>

例如,获得config命令的手册:

$ git help config

3.获取Git仓库

有两种取得Git项目仓库的方法。一种是从一个服务器克隆一个现有的Git仓库。另一种是在现有项目和目录下导入所有文件到Git中。

3.1 克隆现有的仓库

克隆仓库的命令格式是:git clone [url]。比如,要克隆Github上面的python.git。

$ git clone https://github.com/TheAlgorithms/Python.git

这会在当前目录下创建一个名为“Python”的目录,并在这个目录下初始化一个.git文件夹,从远程仓库拉取下所有数据放入.git文件夹,然后从中人去最新版本的文件的拷贝。

bj@ubuntu:$ git clone https://github.com/TheAlgorithms/Python.git
Cloning into 'Python'...
remote: Enumerating objects: 8, done.
remote: Counting objects: 100% (8/8), done.
remote: Compressing objects: 100% (8/8), done.
remote: Total 3649 (delta 1), reused 3 (delta 0), pack-reused 3641
Receiving objects: 100% (3649/3649), 7.18 MiB | 530.00 KiB/s, done.
Resolving deltas: 100% (1882/1882), done.

如果想在克隆远程仓库的时候,自定义本地仓库的名字,可以使用如下命令:

$ git clone https://github.com/TheAlgorithms/Python.git myPython

3.2 在现有目录中初始化仓库

如果不克隆现有仓库,而是打算使用Git来对现有的项目进行管理。假设有一个项目的目录为:~/program/HelloWorld,只需要进入该项目的目录并输入:

$ git init

执行上名的命令,会输出以下结果:

bj@ubuntu:~/program/HelloWorld$ git init
Initialized empty Git repository in /home/yangqi/program/HelloWorld/.git/

该命令会创建一个名为.git的子目录,这个子目录含有初始化的Git仓库中所有的必须文件。但是,我们仅仅是只做了一个初始化操作,项目里的文件还没有被跟踪。

如果是在一个已经存在的文件的文件夹(而不是空文件夹)中初始化GIt仓库来进行版本控制的话,应该可以跟踪这些文件并提交。可以通过git add命令来实现对指定文件的跟踪,然后执行git commit提交。(进入HelloWorld.java所在的文件目录下)

$ git add HelloWorld.java
$ git commit -m 'initial project version'
On branch master
nothing to commit, working tree clean

3.3 更新提交到仓库

3.3.1 检查当前文件的状态

要查看那些文件处于什么状态,可以使用git status。如果在克隆仓库后立即使用此命令,会看到类似与以下的输出:

$ git status
On branch master
nothing to commit, working tree clean

这说明现在你的工作目录相当干净,也就是说所有已经跟踪的文件在上次提交后都未被更改过。此外,上面的信息还表明,当前目录下没有出现任何处于未跟踪状态的新文件,否则 Git 会在这里列出来。 最后,该命令还显示了当前所在分支,并告诉你这个分支同远程服务器上对应的分支没有偏离。现在,分支名是 “master”, 这是默认的分支名。

现在,在项目目录下创建一个myApp.txt文件,并且进行编辑。之后使用git status命令,将看到一个新的跟踪文件:

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

	myApp.txt

nothing added to commit but untracked files present (use "git add" to track)
3.3.2 跟踪新文件

使用命令git add开始跟踪一个文件。跟踪myApp.txt文件,运行:

$ git add myApp.txt

此时再运行git status命令,会看到myApp.txt文件已经被跟踪,并且处于暂存状态:

$ git status 
On branch master
Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)

	new file:   myApp.txt

只要在Changes to be committed这行下面的,就说明已经是暂存状态。如果此时提交,那麽该文件此时此刻的版本将被保留在历史记录中。

3.3.3 暂存已修改文件

我们重新创建一个README.md文件,并对其进行暂存。

$ git add README.md 
$ git status
On branch master
Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)

	new file:   README.md

现在我们对README.md文件进行修改。

$ gedit README.md 
$ git status 
On branch master
Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)

	new file:   README.md

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:   README.md

我们会看到README.md文件同时出现在Changes not staged for commit这行和Changes to be committed下面,说明已经跟踪的文件内容发生了变化,但是还没有放到暂存区。要暂存这次更新,需要执行git add命令。这是一个多功能命令:可以用它来跟踪新文件,或者把已经跟踪的文件放到暂存区,还能用于合并时把有冲突的文件标记为已解决状态等。

如果此时提交,只会将放在暂存区域的提交至仓库,但并不会影响还未进行跟踪的更改过后的文件。

$ git commit -m 'initial project version'
[master 4b1e729] initial project version
 1 file changed, 1 insertion(+)
 create mode 100644 README.md
$ 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:   README.md

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

3.3.4 状态简览

使用git status命令输出的十分详细。如果使用git status -s命令或者git status --short命令,将会得到一种更为紧凑的格式输出。

$ git status -s
AM 11.txt
 M README.md
?? 22.txt

新添加的未跟踪文件前面有 ?? 标记,新添加到暂存区中的文件前面有 A 标记,修改过的文件前面有 M 标记。但是你会注意到第一行有AM标识,它是指将文件已经放入了缓存去后,又对文件进行了更改。

3.3.5 忽略文件

有些文件我们不希望它出现在未跟踪文件列表。通常都是一些自动生成的文件,比如日志文件等。这种情况我们可以创建一个名为.gitignore的文件,列出要忽略的文件模式。

3.3.6 查看已暂存和未暂存的修改

如果你想知道你对文件进行了那些地方的修改,可以使用git diff命令。

$ git diff
diff --git a/11.txt b/11.txt
index e69de29..764f6c2 100644
--- a/11.txt
+++ b/11.txt
@@ -0,0 +1 @@
+士大夫使得
diff --git a/README.md b/README.md
index 34b656e..1cddb57 100644
--- a/README.md
+++ b/README.md
@@ -1 +1,5 @@
-我是一个暂存文件
+我是一个暂存文件,
+
+第一次更改
+
+都是发生
\ No newline at end of file

注意:git diff本身只显示尚未暂存的改动,而不是自上次提交以来所有的改动。可以使用git diff --cached或者git diff --staged来查看已经暂存起来的变化。

$ git diff --cached 
diff --git a/11.txt b/11.txt
new file mode 100644
index 0000000..e69de29
3.3.7 提交更新

现在可以准备提交更新了,一定要确认还有什么修改过得文件没有被git add过,否则提交的时候不会记录这些还没有暂存起来的变化。所以,每次提交前使用git status看一下,是不是都暂存起来了。最后提交使用git commit命令。

$ git add .
$ git status
On branch master
Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)

	new file:   11.txt
	new file:   22.txt
	modified:   README.md
	
$ git commit -m 'initial project version'
[master 1c106af] initial project version
 3 files changed, 7 insertions(+), 1 deletion(-)
 create mode 100644 11.txt
 create mode 100644 22.txt

3.3.8 跳过使用暂存区域

尽管使用暂存区域的方式可以精心准备要提交的细节,但有时候这么做显得有待你繁琐。Git提供了一个跳过使用暂存区域的方式,只需要在提交的时候,给git commit加上-a选项,Git就会自动把所有已经跟踪过的文件暂存起来一起提交,从而跳过git add步骤:

git commit -a -m 'added new benchmarks'
[master 83e38c7] added new benchmarks
 1 file changed, 5 insertions(+), 0 deletions(-)
3.3.9 移除文件

要从Git中移除某个文件,就必须要从已跟踪文件清单中移除(也就是说,从暂存区域移除),然后提交。可以用git rm命令完成此项工作,并连带从工作目录中删除指定的文件。

git rm 命令后面可以列出文件或者目录的名字,也可以使用 glob 模式。 比方说:
$ git rm log/\*.log
删除log/目录下扩展名为.log的所有文件
$ git rm -f 33.txt 
rm '33.txt'
$ ls -l
total 20
-rw-r--r-- 1 yangqi yangqi  16 3月  22 11:25 11.txt
-rw-r--r-- 1 yangqi yangqi   7 3月  22 11:25 22.txt
-rw-rw-r-- 1 yangqi yangqi 122 3月  17 22:50 HelloWorld.java
-rw-r--r-- 1 yangqi yangqi  32 3月  22 10:06 myApp.txt
-rw-r--r-- 1 yangqi yangqi  58 3月  22 11:25 README.md

3.3.10 移动文件
$ git mv file_from file_to

例如将22.txt移动为33.txt,其实也就是重命名文件。

$ git mv 22.txt 33.txt
$ ls -l
total 20
-rw-r--r-- 1 yangqi yangqi  16 3月  22 11:25 11.txt
-rw-r--r-- 1 yangqi yangqi   7 3月  22 11:25 33.txt
-rw-rw-r-- 1 yangqi yangqi 122 3月  17 22:50 HelloWorld.java
-rw-r--r-- 1 yangqi yangqi  32 3月  22 10:06 myApp.txt
-rw-r--r-- 1 yangqi yangqi  58 3月  22 11:25 README.md
$ git status 
On branch master
Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)

	renamed:    22.txt -> 33.txt

3.4 查看提交历史

在提交了若干更新,有克隆了某个项目之后,如果你想看一下历史,使用git log命令。

$ git log
commit 1c106af241e9f0b63cc43e1b26a74b922c0934d8 (HEAD -> master)
Author: yangqi199808 <yangqi199808@yeah.net>
Date:   Fri Mar 22 11:52:04 2019 +0800

    initial project version

commit 4b1e729b231601329f56e9378dd6acf5f0debae5
Author: yangqi199808 <yangqi199808@yeah.net>
Date:   Fri Mar 22 11:08:04 2019 +0800

    initial project version

commit e18471471dde9a80195d14fc8cf44b29f059cf58
Author: yangqi199808 <yangqi199808@yeah.net>
Date:   Fri Mar 22 10:47:37 2019 +0800

默认不使用任何参数,git log会按照时间列出所有的更新,最近的更新在最上方。git log最常用的一个选项是-a,用来显示每次提交的内容差异。也可以使用-2来显示最近两次提交。

$ git log -p
commit 1c106af241e9f0b63cc43e1b26a74b922c0934d8 (HEAD -> master)
Author: yangqi199808 <yangqi199808@yeah.net>
Date:   Fri Mar 22 11:52:04 2019 +0800

    initial project version

diff --git a/11.txt b/11.txt
new file mode 100644
index 0000000..764f6c2
--- /dev/null
+++ b/11.txt
@@ -0,0 +1 @@
+士大夫使得
diff --git a/22.txt b/22.txt
new file mode 100644
index 0000000..e6076a0

$ git log -2
commit 1c106af241e9f0b63cc43e1b26a74b922c0934d8 (HEAD -> master)
Author: yangqi199808 <yangqi199808@yeah.net>
Date:   Fri Mar 22 11:52:04 2019 +0800

    initial project version

commit 4b1e729b231601329f56e9378dd6acf5f0debae5
Author: yangqi199808 <yangqi199808@yeah.net>
Date:   Fri Mar 22 11:08:04 2019 +0800

    initial project version

如果你想看到每次提交的简略的统计信息,可以使用–stat选项。

$ git log --stat
commit 1c106af241e9f0b63cc43e1b26a74b922c0934d8 (HEAD -> master)
Author: yangqi199808 <yangqi199808@yeah.net>
Date:   Fri Mar 22 11:52:04 2019 +0800

    initial project version

 11.txt    | 1 +
 22.txt    | 1 +
 README.md | 6 +++++-
 3 files changed, 7 insertions(+), 1 deletion(-)

commit 4b1e729b231601329f56e9378dd6acf5f0debae5
Author: yangqi199808 <yangqi199808@yeah.net>
Date:   Fri Mar 22 11:08:04 2019 +0800

    initial project version

另外还有一个常用的选项是–pretty。这个选项可以使用不同于默认格式的方式提交历史信息。

$ git log --pretty=oneline
1c106af241e9f0b63cc43e1b26a74b922c0934d8 (HEAD -> master) initial project version
4b1e729b231601329f56e9378dd6acf5f0debae5 initial project version
e18471471dde9a80195d14fc8cf44b29f059cf58 initial project version
58f1ea0a5548184cac2a4e427ac09cda9ec446cf initial project version
$ git log --pretty=short 
commit 1c106af241e9f0b63cc43e1b26a74b922c0934d8 (HEAD -> master)
Author: yangqi199808 <yangqi199808@yeah.net>

    initial project version

commit 4b1e729b231601329f56e9378dd6acf5f0debae5
Author: yangqi199808 <yangqi199808@yeah.net>

    initial project version

commit e18471471dde9a80195d14fc8cf44b29f059cf58
Author: yangqi199808 <yangqi199808@yeah.net>

    initial project version

commit 58f1ea0a5548184cac2a4e427ac09cda9ec446cf
$ git log --pretty=full
commit 1c106af241e9f0b63cc43e1b26a74b922c0934d8 (HEAD -> master)
Author: yangqi199808 <yangqi199808@yeah.net>
Commit: yangqi199808 <yangqi199808@yeah.net>

    initial project version

commit 4b1e729b231601329f56e9378dd6acf5f0debae5
Author: yangqi199808 <yangqi199808@yeah.net>
Commit: yangqi199808 <yangqi199808@yeah.net>

    initial project version

commit e18471471dde9a80195d14fc8cf44b29f059cf58
Author: yangqi199808 <yangqi199808@yeah.net>
Commit: yangqi199808 <yangqi199808@yeah.net>

$ git log --pretty=fuller
commit 1c106af241e9f0b63cc43e1b26a74b922c0934d8 (HEAD -> master)
Author:     yangqi199808 <yangqi199808@yeah.net>
AuthorDate: Fri Mar 22 11:52:04 2019 +0800
Commit:     yangqi199808 <yangqi199808@yeah.net>
CommitDate: Fri Mar 22 11:52:04 2019 +0800

    initial project version

commit 4b1e729b231601329f56e9378dd6acf5f0debae5
Author:     yangqi199808 <yangqi199808@yeah.net>
AuthorDate: Fri Mar 22 11:08:04 2019 +0800
Commit:     yangqi199808 <yangqi199808@yeah.net>
CommitDate: Fri Mar 22 11:08:04 2019 +0800

    initial project version

3.5 撤销操作

在任何一个阶段,也有都会有一些错误的操作或者要撤销某些操作。

3.5.1 –amend 选项

有时候我们提交完了才可以漏掉了几个文件没有添加,或者提交信息写错了,此时可以使用 --amend 选项的提交命令尝试重新提交:

$ git commit --amend 
[master efab520] initial project version
 Date: Fri Mar 22 11:52:04 2019 +0800
 3 files changed, 7 insertions(+), 1 deletion(-)
 create mode 100644 11.txt
 create mode 100644 33.txt

这个命令会将暂存区中的文件提交。 如果自上次提交以来你还未做任何修改(例如,在上次提交后马上执行了此命令),那么快照会保持不变,而你所修改的只是提交信息。文本编辑器启动后,可以看到之前的提交信息。 编辑后保存会覆盖原来的提交信息。

3.5.2 取消暂存的文件

已经修改了两个文件并且想要将它们作为两次独立的修改提示,但是却意外的输入了 git add * 暂存了它们两个。但是要取消其中一个,可以使用 git reset HEAD 来取消暂存。

$ git add *
$ git status
On branch master
Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)

	new file:   44.txt
	new file:   55.txt

$ git reset HEAD 55.txt
$ git status 
On branch master
Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)

	new file:   44.txt

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

	55.txt
3.5.3 撤销对文件的修改

例如,我们删除33.txt,但是又想撤销对文件的修改:

$ git status 
On branch master
Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)

	new file:   55.txt

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:    33.txt

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

	44.txt
# 按照上面的提示进行操作
$ git checkout -- 33.txt
$ git status 
On branch master
Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)

	new file:   55.txt

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

	44.txt

我们使用 ls -l 查看当前目录中的文件:

$ ls -l
total 24
-rw-r--r-- 1 yangqi yangqi  16 3月  22 11:25 11.txt
-rw-r--r-- 1 yangqi yangqi   7 3月  22 13:45 33.txt
-rw-r--r-- 1 yangqi yangqi   0 3月  22 13:34 44.txt
-rw-r--r-- 1 yangqi yangqi  14 3月  22 13:39 55.txt
-rw-rw-r-- 1 yangqi yangqi 122 3月  17 22:50 HelloWorld.java
-rw-r--r-- 1 yangqi yangqi  32 3月  22 10:06 myApp.txt
-rw-r--r-- 1 yangqi yangqi  58 3月  22 11:25 README.md

可以看到已经删除的文件33.txt又重新回来了。

4.程序仓库的使用

4.1 查看远程仓库

如果想要查看已经配置好的远程仓库服务器,可以使用 git remote 命令。它会列出你指定的每一个远程服务器的简写。如果已经克隆了自己的仓库,那么至少可以看到 origin ,这是Git给你克隆的仓库服务器的默认名字:

$ git clone https://github.com/yangqi199808/ionic-myApp.git
Cloning into 'ionic-myApp'...
remote: Enumerating objects: 3, done.
remote: Counting objects: 100% (3/3), done.
remote: Compressing objects: 100% (2/2), done.
remote: Total 3 (delta 0), reused 0 (delta 0), pack-reused 0
Unpacking objects: 100% (3/3), done.
$ cd ionic-myApp/
$ git remote 
origin

也可以使用指定选项 -v ,会显示需要读写远程仓库使用的Git保存的简写与其对应的URL。

$ git remote -v
origin	https://github.com/yangqi199808/ionic-myApp.git (fetch)
origin	https://github.com/yangqi199808/ionic-myApp.git (push)

4.2 添加远程仓库

添加一个新的远程Git仓库,同时指定一个可以轻松引用的简写:

$ git remote add yangqi https://github.com/yangqi199808/first.git
$ git remote 
origin
yangqi

4.3 从远程仓库中抓取与拉取

从远程仓库中获得数据,可以执行:

$ git fetch [remote-name]

这个命令会访问远程仓库,从中拉取还没有的数据。执行完成后,将会拥有那个远程仓库中所有分支的引用,可以随时合并或查看。

如果使用 clone 命令克隆了一个仓库,命令会自动将其添加为远程仓库并默认以 “origin” 为简写。 所以,git fetch origin 会抓取克隆(或上一次抓取)后新推送的所有工作。 必须注意 git fetch origin 命令会将数据拉取到本地仓库 - 它并不会自动合并或修改当前的工作。

如果你有一个分支设置为跟踪一个远程分支,可以使用 git pull 命令来自动的抓取然后合并远程分支到当前分支。 这对你来说可能是一个更简单或更舒服的工作流程;默认情况下,git clone 命令会自动设置本地 master 分支跟踪克隆的远程仓库的 master 分支(或不管是什么名字的默认分支)。 运行 git pull 通常会从最初克隆的服务器上抓取数据并自动尝试合并到当前所在的分支。

$ git fetch origin 
remote: Enumerating objects: 3, done.
remote: Counting objects: 100% (3/3), done.
remote: Compressing objects: 100% (2/2), done.
remote: Total 3 (delta 0), reused 0 (delta 0), pack-reused 0
Unpacking objects: 100% (3/3), done.
From https://github.com/yangqi199808/ionic-myApp
 * [new branch]      master     -> origin/master

$ git pull origin 
You asked to pull from the remote 'origin', but did not specify
a branch. Because this is not the default configured remote
for your current branch, you must specify a branch on the command line.

4.3 推送到远程仓库

当你想分享项目时,必须将其推送到仓库。当你想要将 master 分支推送到 origin 服务器时,可以使用 git push [remote-name] [branch-name]

$ git push yangqi master
Username for 'https://github.com': yangqi199808
Password for 'https://yangqi199808@github.com': 
Counting objects: 14, done.
Delta compression using up to 4 threads.
Compressing objects: 100% (9/9), done.
Writing objects: 100% (14/14), 1.28 KiB | 1.28 MiB/s, done.
Total 14 (delta 1), reused 0 (delta 0)
remote: Resolving deltas: 100% (1/1), done.
To https://github.com/yangqi199808/first.git
 * [new branch]      master -> master

4.4 查看远程仓库

如果想要查看某一个远程仓库的更多信息,可以使用 git remote show [remote-name] 命令。

$ git remote show yangqi
* remote yangqi
  Fetch URL: https://github.com/yangqi199808/first.git
  Push  URL: https://github.com/yangqi199808/first.git
  HEAD branch: master
  Remote branch:
    master tracked
  Local ref configured for 'git push':
    master pushes to master (up to date)

它会列出远程仓库的URL与跟踪分支信息。这些信息十分有用,它告诉你正处于 master 分支,并且如果运行 git pull ,就会抓取所有的远程引用,然后将 master 分支合并到本地 master 分支,也会列出拉取到的所有远程引用。

如果要移除一个远程仓库,可以使用 git remote rm [remote-name]

$ git remote rm yangqi