通过一顿操作来熟悉 Git 是不二法门。
创建仓库
请自行准备好 git
环境。
创建服务器裸仓库
git init
: 将当前的目录转换成一个 git
仓库git init <directory>
: 在指定目录创建一个空的 git
仓库git init --bare <project-name>.git
: 裸库往往被创建用于作为大家一起工作的共享库,每一个人都可以往里面 push
自己的本地修改。服务器上 bare
创建的仓库,主要用来连接,同步,协调。记录每个人本地仓库的记录,而不存放项目源代码。而每个开发人员自己电脑上分别有个小仓库,存放源代码及自己的改动
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
| // 登录远程服务器
$ ssh <user>@<host>
// 进入操作目录
$ cd /path/to/repository
// 创建祼仓库
$ git init --bare <project-name>.git
// 退出远程服务器,进入本地终端
$ git init <directory>
$ touch README.md
$ git add README.md
$ git commit -m "Initial commit"
$ git remote add origin <user>@<host>:/path/to/repository/<project-name>.git
$ git push -u origin master
// 其它成员克隆仓库
$ git clone <user>@<host>:/path/to/repository/<project-name>.git
|
创建本地仓库
初始化本地仓库
1
2
3
4
5
6
7
| // 创建本地仓库
$ mkdir example
$ cd example
$ git init
$ touch README.md
$ git add README.md
$ git commit -m "Initial commit"
|
关联远程仓库
关联多个仓库需要给不同的远程仓库起一个别名,请自行在 gitee 和 github 上创建空仓库。
1
2
3
4
5
| $ git remote add gitee git@gitee.com:user/project.git
$ git push -u gitee master
或
$ git remote add github https://github.com/user/project.git
$ git push -u github master
|
分支跟踪远程分支
1
2
| // 设置让本地某个分支跟踪远程的某个分支
$ git branch --set-upstream-to=origin/<branch> <branch>
|
克隆远程仓库
1
2
3
| $ git clone <user>@<host>:/path/to/repository/<project>.git
或
$ git clone https://gitee.com/user/<project>.git
|
基本操作
初始化仓库
1
2
3
| $ cd ~/Desktop && mkdir example && cd example
$ git init
Initialized empty Git repository in /Users/majinyun/Desktop/example/.git/
|
忽略文件
GitHub 官方提供的 忽略文件模版
.gitignore
文件格式:
- 所有空行或者以注释符号
#
开头的行都会被 git
忽略 - 可以使用标准的
glob
模式匹配 - 匹配模式最后跟反斜杠
/
说明要忽略的是目录 - 要忽略指定模式以外的文件或目录,可以在模式前加上惊叹号
!
取反
添加文件
空目录是不能提交到仓库中的,至少要保证目录中有一个文件。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
| // 创建一个 README.md 文件
$ touch README.md
// 查看仓库状态
$ git status
On branch master
No commits yet
Untracked files:
(use "git add <file>..." to include in what will be committed)
README.md
nothing added to commit but untracked files present (use "git add" to track)
// 如果这个阶段你发现文件创建错误了(本不应该放置在此目录中或不需要此文件或者其它任何原因),直接删除掉即可,否则继续以下操作
$ rm -f README.md
// 添加 README.md 文件到暂存区
$ git add README.md
// 查看仓库状态
$ git status
On branch master
No commits yet
Changes to be committed:
(use "git rm --cached <file>..." to unstage)
new file: README.md
// 如果这个阶段你发现此文件不应该被添加到暂存区,请不要粗暴的 rm 掉,而是使用 git rm 命令干掉它
$ git rm --cached README.md
|
仓库状态
1
2
3
| $ git status
On branch master
nothing to commit, working tree clean
|
提交文件
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
| // 将暂存区的文件提交到仓库,正常情况下会如下面的操作一样,显示文件已经被加入到版本库中,但也有不正常的情况
$ git commit -m "Add README.md"
[master (root-commit) a384a2b] Add README.md
1 file changed, 0 insertions(+), 0 deletions(-)
create mode 100644 README.md
// 这个就是提交时的不正常情况,什么意思呢?第一种说法的意思是需要你配置一下仓库的用户名称和邮箱地址,这个小意思,我们直接来个全局配置和局部配置就搞定了。第二种说法的意思是你在完成上面的操作之后,可以修复用于此提交的标识,说白了就是你提交到仓库后还可以进行编辑提交记录的注释信息(就是就对万一将本次提交记录的注释信息写错的情况),它会弹出你所配置的编辑器让你修改提交记录的注释信息,很遗憾这个只修改最后一个提交记录的注释信息,那么问题来了,怎么修改前 N 次的的某个提交记录的注释信息呢,这里暂时先不探究,这个涉及到 rebase 操作,足以让我再折腾一篇来专门说这种情况
$ git commit -m "Add README.md"
[master (root-commit) a384a2b] Add README.md
Committer: user <user@user.com>
Your name and email address were configured automatically based
on your username and hostname. Please check that they are accurate.
You can suppress this message by setting them explicitly:
git config --global user.name "Your Name"
git config --global user.email you@example.com
After doing this, you may fix the identity used for this commit with:
git commit --amend --reset-author
1 file changed, 0 insertions(+), 0 deletions(-)
create mode 100644 README.md
// 配置用户和邮箱交提交到仓库,将用户和邮箱换成你自己的,这个时间代码已经被提交到仓库
$ git config user.name "yourname"
$ git config user.email "yourname@email.com"
// 查看仓库状态
$ git status
On branch master
nothing to commit, working tree clean
|
修改最后一次提交日志信息
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
| $ vim README.md
[1]: https://symfony.com
$ git add README.md
$ git commit -m "Add symfony link"
[master 98a19c3] Add symfony link
1 file changed, 1 insertion(+)
$ git commit --amend
Add symfony website link # 编辑此信息
# Please enter the commit message for your changes. Lines starting
# with '#' will be ignored, and an empty message aborts the commit.
#
# Date: Sun Dec 30 19:22:08 2018 +0800
#
# On branch master
# Changes to be committed:
# modified: README.md
#
[master abe0281] Add symfony website link
Date: Sun Dec 30 19:22:08 2018 +0800
1 file changed, 1 insertion(+)
|
修改最后一次提交记录时的用户信息
1
2
3
4
5
| $ git commit --amend --author="peter <peter@dot.org>"
[master facc111] Add symfony website link
Author: peter <peter@dot.org>
Date: Sun Dec 30 19:22:08 2018 +0800
1 file changed, 1 insertion(+)
|
撤销对文件内容的更改
1
2
3
4
5
6
7
8
9
10
11
12
13
| $ vim README.md
[1]: https://symfony.com
[2]: https://symfony.com/projects
$ 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")
$ git checkout -- README.md
|
提交文件变更到仓库
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
| $ vim README.md
[1]: https://symfony.com
[2]: https://symfony.com/projects
$ 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")
$ git add README.md
$ git commit -m "Add projects link"
[master 7d8fcb9] Add projects link
1 file changed, 1 insertion(+)
|
回滚仓库到某个提交
1
2
3
4
5
6
7
8
9
| $ git log --oneline
7d8fcb9 (HEAD -> master) Add projects link
facc111 Add symfony website link
a384a2b Add README.md
$ git reset --hard facc111
HEAD is now at facc111 Add symfony website link
$ git log --oneline
facc111 (HEAD -> master) Add symfony website link
a384a2b Add README.md
|
撤销工作区和暂存区
--soft
:当前分支重置到指定 commit 记录位置,索引和工作树不变--mixed
:当前分支重置到指定 commit 记录位置,索引被更新,工作树不变--hard
:当前分支重置到指定 commit 记录位置,索引和工作树都更新
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
| $ touch index.{html,js,css}
$ git status
On branch master
Untracked files:
(use "git add <file>..." to include in what will be committed)
index.css
index.html
index.js
nothing added to commit but untracked files present (use "git add" to track)
$ $ git add .
$ git status
On branch master
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)
new file: index.css
new file: index.html
new file: index.js
// 只撤销暂存区
$ git reset HEAD
// 全部撤销
$ git reset --hard HEAD
HEAD is now at facc111 Add symfony website lin
|
查看已暂存和未暂存的更新
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
| $ vim README.md
[1]: https://symfony.com
[2]: https://symfony.com/projects
$ git add README.md
$ vim README.md
[1]: https://symfony.com
[2]: https://symfony.com/projects
[3]: https://symfony.com/doc/current/reference/requirements.html
// 比较工作目录中当前文件和暂存区域快照之间的差异,也就是修改之后还没有暂存起来的变化内容
$ git diff
diff --git a/README.md b/README.md
index 56737ed..4a93303 100644
--- a/README.md
+++ b/README.md
@@ -1,2 +1,3 @@
[1]: https://symfony.com
[2]: https://symfony.com/projects
+[3]: https://symfony.com/doc/current/reference/requirements.html
// 查看已经暂存起来的文件和上次提交时的快照之间的差异
$ git diff --cached
diff --git a/README.md b/README.md
index 55c6709..56737ed 100644
--- a/README.md
+++ b/README.md
@@ -1 +1,2 @@
[1]: https://symfony.com
+[2]: https://symfony.com/projects
或者
// 查看已经暂存起来的文件和上次提交时的快照之间的差异
$ git diff --staged
diff --git a/README.md b/README.md
index 55c6709..56737ed 100644
--- a/README.md
+++ b/README.md
@@ -1 +1,2 @@
[1]: https://symfony.com
+[2]: https://symfony.com/projects
// 跳过使用暂存区域,git 会自动把所有已经跟踪过的文件暂存起来一并提交,从而跳过 git add 步骤
$ git status
On branch master
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)
modified: 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
$ git commit -am "Add projects and requirements link"
[master 7778db8] Add projects and requirements link
1 file changed, 2 insertions(+)
$ git status
On branch master
nothing to commit, working tree clean
|
移除文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
| // 误删了文件,期望不产生提交记录就把文件干掉(此文件从来没提交到仓库中),通过以下的操作就可以看到此文件恢复到之前创建时的状态,此时你可以考虑删除或者做其它更改
$ touch index.html && git add index.html && rm index.html
remove index.html? y
$ git status
On branch master
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)
new file: index.html
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: index.html
$ git checkout -- index.html
$ git status
On branch master
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)
new file: index.html
$ git reset HEAD index.html
$ git status
On branch master
Untracked files:
(use "git add <file>..." to include in what will be committed)
index.html
nothing added to commit but untracked files present (use "git add" to track)
// 把文件从暂存区域移除,但仍然希望保留在当前工作区
$ git add index.html
$ git status
On branch master
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)
new file: index.html
$ git rm --cached index.html
$ git status
On branch master
Untracked files:
(use "git add <file>..." to include in what will be committed)
index.html
nothing added to commit but untracked files present (use "git add" to track)
// 将未加入暂存区的文件全部清理掉,即将工作区的变更全部清理掉,需要谨慎操作
$ git clean -df
Removing index.html
|
移动或者重命名文件
1
2
3
4
5
6
7
8
9
10
11
12
13
| $ touch index.php
$ git add index.php
$ git commit -m "Add index.php"
[master da3c74c] Add index.php
1 file changed, 0 insertions(+), 0 deletions(-)
create mode 100644 index.php
$ git mv index.php index.html
$ git status
On branch master
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)
renamed: index.php -> index.html
|
差异比较
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
| // 比较两个分支的所有差异
$ git diff master develop
diff --git a/.editorconfig b/.editorconfig
deleted file mode 100644
index e69de29..0000000
diff --git a/README.md b/README.md
index f6f24a8..c0cd272 100644
--- a/README.md
+++ b/README.md
@@ -3,4 +3,3 @@
[3]: https://symfony.com/doc/current/reference/requirements.html
[4]: https://symfony.com/doc/current/setup.html
[5]: http://semver.org
-[6]: https://symfony.com/doc/current/contributing/community/releases.html
// 比较两个提交记录的所有差异
$ git diff fe3b3cf 688088f
diff --git a/.editorconfig b/.editorconfig
deleted file mode 100644
index e69de29..0000000
diff --git a/README.md b/README.md
index f6f24a8..c0cd272 100644
--- a/README.md
+++ b/README.md
@@ -3,4 +3,3 @@
[3]: https://symfony.com/doc/current/reference/requirements.html
[4]: https://symfony.com/doc/current/setup.html
[5]: http://semver.org
-[6]: https://symfony.com/doc/current/contributing/community/releases.html
// 比较两个提交中的某个文件的差异
$ git diff fe3b3cf 688088f -- README.md
diff --git a/README.md b/README.md
index f6f24a8..c0cd272 100644
--- a/README.md
+++ b/README.md
@@ -3,4 +3,3 @@
[3]: https://symfony.com/doc/current/reference/requirements.html
[4]: https://symfony.com/doc/current/setup.html
[5]: http://semver.org
-[6]: https://symfony.com/doc/current/contributing/community/releases.html
|
储藏
当你正在进行项目中某一部分的工作,里面的东西处于一个比较杂乱的状态,而你想转到其他分支上进行一些工作。问题是,你不想提交进行了一半的工作,否则以后你无法回到这个工作点。git stash
就是解决这种问题的。
储藏任务
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
| // 假设目前工作进行了一段时间后,仓库的目前的状态
$ git status
On branch master
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)
modified: index.css
modified: index.html
modified: index.js
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: index.html
// 此时由于紧急的任务或者 bug 需要解决,暂时将之前做的任务暂存起来
$ git stash
Saved working directory and index state WIP on master: fe3b3cf Integrating submission logs
// 获取一个干净的工作目录
$ git status
On branch master
nothing to commit, working tree clean
|
查看储藏任务列表
1
2
3
| $ git stash list
stash@{0}: WIP on master: fe3b3cf Integrating submission logs
stash@{1}: WIP on master: fe3b3cf Integrating submission logs
|
应用最近的储藏
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
| // apply 选项并不会删除储藏
$ git stash apply
或
$ git stash apply stash@{0}
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")
// 此时应用储藏时与之前储藏时的文件状态不一致
$ git stash apply stash@{1}
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: index.css
modified: index.html # 看这个文件之前储藏时的状态
modified: index.js
// 带上一个 --index 的选项来告诉命令重新应用被暂存的变更
$ git stash apply stash@{0} --index
On branch master
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)
modified: index.css
modified: index.html
modified: index.js
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: index.html # 文件暂存状态恢复了
// 应用储藏后立即删除储藏
$ git stash pop --index
On branch master
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)
modified: index.css
modified: index.html
modified: index.js
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: index.html
Dropped refs/stash@{0} (5c5c3fe5374020b5d4a1b0d5303b0cb932227134)
|
删除储藏
1
2
| $ git stash drop stash@{0}
Dropped stash@{0} (e2ffa6a2b49d31703266cf6668f2b51f94e9d62f)
|
取消储藏
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
| // 在某些情况下,你可能想应用储藏的修改,在进行了一些其他的修改后,又要取消之前所应用储藏的修改
$ 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: index.html
no changes added to commit (use "git add" and/or "git commit -a")
$ git stash
Saved working directory and index state WIP on master: fe3b3cf Integrating submission logs
$ git stash list
stash@{0}: WIP on master: fe3b3cf Integrating submission logs
$ git stash apply stash@{0} --index
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: index.html
no changes added to commit (use "git add" and/or "git commit -a")
// 取消应用的储藏,没有指定默认为最近一次储藏
$ git stash show -p stash@{0} | git apply -R
或
$ git stash show -p | git apply -R
|
从储藏中创建分支
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
| $ git stash branch testchanges
Switched to a new branch 'testchanges'
On branch testchanges
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)
modified: index.css
modified: index.html
modified: index.js
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: index.html
Dropped refs/stash@{0} (9d514109f5cf6c23c75297af595189d5af839693)
|