Git初始设置
设置使用Git时需要的用户名和邮箱
$ git config --global user.name 'Firstname Lastname'
$ git config --global user.email "your_email@example.com"
初始化仓库
$ mkdir myApp
$ cd myApp
$ git init
Initialized empty Git repository in /Users/INST/Desktop/myApp/.git/
如果初始化成功,执行了 git init命令的目录下就会生成 .git 目 录。这个 .git 目录里存储着管理当前目录内容所需的仓库数据。
在 Git 中,我们将这个目录的内容称为“附属于该仓库的工作树”。 文件的编辑等操作在工作树中进行,然后记录到仓库中,以此管理文件 的历史快照。如果想将文件恢复到原先的状态,可以从仓库中调取之前 的快照,在工作树中打开。开发者可以通过这种方式获取以往的文件。 具体操作指令我们将在后面详细解说。
查看仓库的工作状态
$ git status
On branch master
Initial commit
结果显示了我们当前正处于 master 分支下。关于分支我们会在不久 后讲到,现在不必深究。接着还显示了没有可提交的内容。所谓提交
(Commit),是指“记录工作树中所有文件的当前状态”。 尚没有可提交的内容,就是说当前我们建立的这个仓库中还没有记 录任何文件的任何状态。
向暂存区中添加文件
如果只是用 Git 仓库的工作树创建了文件,那么该文件并不会被记 入 Git 仓库的版本管理对象当中。因此我们用 git status命令查看 README.md 文件时,它会显示在 Untracked files 里。
要想让文件成为 Git 仓库的管理对象,就需要用 git add命令将其 加入暂存区(Stage 或者 Index)中。暂存区是提交之前的一个临时区域。
$ git add README.md
$ git status
# On branch master
将 README.md 文件加入暂存区后,git 果发生了变化。可以看到,README.md文件显示在Changes to be committed 中了。
保存仓库中的历史记录
git commit命令可以将当前暂存区中的文件实际保存至历史记录中,通过这些记录,我们可以从工作树中复原文件
$ git commit -m "First commit"
[master (root-commit) c968230] First commit
1 file changed, 1 insertion(+)
create mode 100644 README.md
-m 参数后的 "First commit"称作提交信息,是对这个提交的概述。
记述详细提交信息
刚才我们只简洁地记述了一行提交信息,如果想要记述得更加详细,请不加- m,直接执行gitcommit命令。执行后编辑器就会启动,并显示如下结果。
$ git commit
# Please enter the commit message for your changes. Lines starting
# with '#' will be ignored, and an empty message aborts the commit.
# On branch master #
# Initial commit
#
# Changes to be committed:
# (use "git rm --cached <file>..." to unstage) #
# new file: README.md
#
在编辑器中记述提交信息的格式如下:
- 第一行:用一行文字简述提交的更改内容
- 第二行:空行
- 第三行以后:记述更改的原因和详细内容
只要按照上面的格式输入,今后便可以通过确认日志的命令或工具 看到这些记录。
在以 #(井号)标为注释的 Changes to be committed(要提 交的更改)栏中,可以查看本次提交中包含的文件。将提交信息按格式 记述完毕后,请保存并关闭编辑器,以 #(井号)标为注释的行不必删 除。随后,刚才记述的提交信息就会被提交。
查看提交日志
git log命令可以查看以往仓库中提交的日志,包括什么人什么时候进行了提交和合并,以及操作之后有何区别。
$ git log
commit 2c2ee0223f54c7512245f7ab3da5ad7e1bbfb30a
Author: Firstname Lastname <your_email@example.com>
Date: Fri Aug 11 09:37:56 2017 +0800
第一行简单文字描述
//空格
只是一个小小的测试
文本
commit c968230beadd590903ee2645387d833596fb0fca
Author: Firstname Lastname <your_email@example.com>
Date: Fri Aug 11 09:30:42 2017 +0800
First commit
INSTdeiMac:myApp Andy$ git log --pretty=short // 只显示提交信息的第一行
commit 2c2ee0223f54c7512245f7ab3da5ad7e1bbfb30a
Author: Firstname Lastname <your_email@example.com>
第一行简单文字描述
commit c968230beadd590903ee2645387d833596fb0fca
Author: Firstname Lastname <your_email@example.com>
$ git log README.md // 只显示单个文件、目录日志
commit c968230beadd590903ee2645387d833596fb0fca
Author: Firstname Lastname <your_email@example.com>
Date: Fri Aug 11 09:30:42 2017 +0800
First commit
显示文件的改动
如果想要查看提交所带来的改动,可以加上参数- p,文件的前后差别就会显示在提交信息中
$ git log -p README.md
commit c968230beadd590903ee2645387d833596fb0fca
Author: Firstname Lastname <your_email@example.com>
Date: Fri Aug 11 09:30:42 2017 +0800
First commit
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..421ac42
--- /dev/null
+++ b/README.md
@@ -0,0 +1 @@
+# git教程
\ No newline at end of file
查看暂存区和工作树之间的差别
git diff
diff --git a/README.md b/README.md index e69de29..cb5dc9f 100644
--- a/README.md
+++ b/README.md
@@ -0,0 +1 @@ +# Git教程
由于我们尚未用git只会显示工作树与最新提交状态之间的差别。
add命令向暂存区添加任何东西,所以程序只会显示工作树与最新提交状态之间的差别。
查看工作树和最新提交的差别
如果现在执行 git diff命令,由于工作树和暂存区的状态并无 差别,结果什么都不会显示。要查看与最新提交的差别,请执行以下 命令。
$ git diff HEAD
diff --git a/README.md b/README.md index e69de29..cb5dc9f 100644
--- a/README.md
+++ b/README.md
@@ -0,0 +1 @@
+# Git教程
不妨养成这样一个好习惯:在执行 g i t
git diff HEAD命令,查看本次提交与上次提交之间有什么差别,等 确认完毕后再进行提交。这里的 HEAD 是指向当前分支中最新一次提交 的指针。
分支操作
显示分支一览表
```
$ git branch
* master //当前只有master分支
```
创建和切换分支
```
$ git checkout -b Feature-A
$ git branch
* Feature-A
master
```
切换回上一个分支
```
$ git checkout -
Switched to branch 'master'
```
像上面这样用“-”(连字符)代替分支名,就可以切换至上一个分 支。当然,将“-”替换成 feature-A 同样可以切换到 feature-A 分支。
feature-A 分支左侧标有“*”,表示当前分支为 feature-A。在这个状 态下像正常开发那样修改代码、执行 g i t a d d命令并进行提交的话, 代码就会提交至 feature-A 分支。像这样不断对一个分支(例如 feature-A)进行提交的操作,我们称为“培育分支”。
分支合并
接下来,我们假设 feature-A 已经实现完毕,想要将它合并到主干分 支 master 中。首先切换到 master 分支。
```
$git checkout - //回到主分支
Switched to branch 'master'
```
然后合并 feature-A 分支。为了在历史记录中明确记录下本次分支合 并,我们需要创建合并提交。因此,在合并时加上 --no-ff参数。
```
$ git merge --no-ff feature-A
```
以图标的方式查看分支
$ git log --graph
-
更改提交的操作,回溯历史版本
Git 的另一特征便是可以灵活操作历史版本。借助分散仓库的优势, 可以在不影响其他仓库的前提下对历史版本进行操作。要让仓库的 HEAD、暂存区、当前工作树回溯到指定状态,需要用 到git rest --hard命令。只要提供目标时间点的哈希值A,就可以完全恢复至该时间点的状态。事不宜迟,让我们执行下面的命令
$ git reset --hard fd0cbf0d4a25f747230694d95cac1be72d33441d
HEAD is now at fd0cbf0 Add index
查看当前仓库执行了哪些操作
$ git reflog
1e4e49d HEAD@{0}: reset: moving to 1e4e49d843f9e23c9665015c520349ec03cf0406
0638c04 HEAD@{1}: reset: moving to HEAD
0638c04 HEAD@{2}: merge feature-A: Merge made by the 'recursive' strategy.
2c2ee02 HEAD@{3}: checkout: moving from Feature-A to master
1e4e49d HEAD@{4}: checkout: moving from master to Feature-A
2c2ee02 HEAD@{5}: checkout: moving from Feature-A to master
1e4e49d HEAD@{6}: commit: Add feature-A
2c2ee02 HEAD@{7}: checkout: moving from master to Feature-A
2c2ee02 HEAD@{8}: checkout: moving from Feature-A to master
2c2ee02 HEAD@{9}: checkout: moving from master to Feature-A
2c2ee02 HEAD@{10}: commit: 第一行简单文字描述
c968230 HEAD@{11}: commit (initial): First commit
消除冲突
$ git merge --no-ff fix-B
Auto-merging README.md
CONFLICT (content): Merge conflict in README.md
Recorded preimage for 'README.md'
Automatic merge failed; fix conflicts and then commit the result.
查看冲突部分并将其解决
# Git教程
<<<<<<< HEAD - feature-A
=======
- fix-B
>>>>>>> fix-B
======= 以上的部分是当前 HEAD 的内容,以下的部分是要合并 的 fix-B 分支中的内容。我们在编辑器中将其改成想要的样子。
# Git教程
- feature-A
- fix-B
压缩历史
```
$ git checkout -b feature-C
Switched to a new branch 'feature-C'
```
推送至远程仓库
添加远程仓库
$ git remote add origin git@github.com:github-book/git-tutorial.git
按照上述格式执行git remote add命令之后,Git会自动将 git@github.com:github-book/git-tutorial.git远程仓库的 名称设置为 origin(标识符)。
推送至远程仓库
推送至 master 分支
如果想将当前分支下本地仓库中的内容推送给远程仓库,需要用到 git push命令。现在假定我们在master分支下进行操作。
$ git push -u origin master
像这样执行git push命令,当前分支的内容就会被推送给远程仓库 origin 的 master 分支。-u参数可以在推送的同时,将 origin 仓库的 master 分 支设置为本地仓库当前分支的 upstream(上游)。添加了这个参数,将来 运行 git pull命令从远程仓库获取内容时,本地仓库的这个分支就可 以直接从 origin 的 master 分支获取内容,省去了另外添加参数的麻烦。执行该操作后,当前本地仓库 master 分支的内容将会被推送到 GitHub 的远程仓库中。在 GitHub 上也可以确认远程 master 分支的内容和本地 master 分支相同。
其他分支也是一样
注意:这个时候肯能会报错,主要原因是远程仓库中的README.md文件不在本地仓库中。
- 方案一 我们只需加上 -f 参数即可push成功 git push -f
- 方案二
git pull --rebase origin master
git push -u origin master
获取远程仓库
$ git clone git@github.com:github-book/git-tutorial.git
执行 git clone命令后我们会默认处于 master 分支下,同时系统 会自动将 origin 设置成该远程仓库的标识符。也就是说,当前本地仓库 的 master 分支与 GitHub 端远程仓库(origin)的 master 分支在内容上是 完全相同的。
$ git branch -a * master
remotes/origin/HEAD -> origin/master remotes/origin/feature-D remotes/origin/master
我们用 git branch -a命令查看当前分支的相关信息。添加 -a 参数可以同时显示本地仓库和远程仓库的分支信息。
结果中显示了 remotes/origin/feature-D,证明我们的远程仓库中已经 有了 feature-D 分支。
获取远程的feature-D分支
$ git checkout -b feature-D origin/feature-D
Branch feature-D set up to track remote branch feature-D from origin. Switched to a new branch 'feature-D'
- b 参数的后面是本地仓库中新建分支的名称。为了便于理解,我 们仍将其命名为 feature-D,让它与远程仓库的对应分支保持同名。新建 分支名称后面是获取来源的分支名称。例子中指定了 origin/feature-D, 就是说以名为 origin 的仓库(这里指 GitHub 端的仓库)的 feature-D 分 支为来源,在本地仓库中创建 feature-D 分支。
推送 feature-D 分支
$ git push
Counting objects: 5, done.
Delta compression using up to 8 threads. Compressing objects: 100% (2/2), done.
Writing objects: 100% (3/3), 281 bytes, done. Total 3 (delta 1), reused 0 (delta 0)
To git@github.com:github-book/git-tutorial.git
ca0f98b..ed9721e feature-D -> feature-D
从远程仓库获取 feature-D 分支,在本地仓库中提交更改,再将 feature-D 分支推送回远程仓库,通过这一系列操作,就可以与其他开发 者相互合作,共同培育 feature-D 分支,实现某些功能
获取最新的远程仓库分支
现在我们放下刚刚操作的目录,回到原先的那个目录下。这边的本
地仓库中只创建了 feature-D 分支,并没有在 feature-D 分支中进行任何提交。然而远程仓库的 feature-D 分支中已经有了我们刚刚推送的提交。 这时我们就可以使用git pull命令,将本地的feature-D分支更新到最新 状态。当前分支为 feature-D 分支。
$ git pull origin feature-D
remote: Counting objects: 5, done.
remote: Compressing objects: 100% (1/1), done. remote: Total 3 (delta 1), reused 3 (delta 1) Unpacking objects: 100% (3/3), done.
From github.com:github-book/git-tutorial
* branch feature-D -> FETCH_HEAD
First, rewinding head to replay your work on top of it... Fast-forwarded feature-D to ed9721e686f8c588e55ec6b8071b669f411486b8.
GitHub 端远程仓库中的 feature-D 分支是最新状态,所以本地仓库 中的 feature-D 分支就得到了更新。今后只需要像平常一样在本地进行提 交再 push 给远程仓库,就可以与其他开发者同时在同一个分支中进行 作业,不断给 feature-D 增加新功能。
如果两人同时修改了同一部分的源代码,push 时就很容易发生冲 突。所以多名开发者在同一个分支中进行作业时,为减少冲突情况的发 生,建议更频繁地进行 push 和 pull 操作
- 删除本地仓库
就是删除文件夹下面的.git文件
find . -name ".git" | xargs rm -Rf
学习资料
1.《Github入门与实践》