- Git命令常规操作
- 常用操作示意图
- 文件的状态变化周期
- 创建文件
[root@gitlab git_data]# touch README
[root@gitlab git_data]# git status #查看工作区状态,Untracked files
[root@gitlab git_data]# git add . #添加到暂存区
[root@gitlab git_data]# git status #查看工作区状态,Changes to be committed
[root@gitlab git_data]# ls .git/objects/ #文件会添加到.git的隐藏目录
15 info pack
[root@gitlab git_data]# git commit -m ‘first commit’ #由工作区提交到本地仓库
[root@gitlab git_data]# git status #查看工作区状态,没有东西需要提交
- 删除git内的文件
要从 Git 中移除某个文件,就必须要从已跟踪文件清单中移除(确切地说,是从暂存区域移除),然后提交。 可以用 git rm 命令完成此项工作,并连带从工作目录中删除指定的文件,这样以后就不会出现在未跟踪文件清单中了。
如果只是简单地从工作目录中手工删除文件,运行 git status 时就会在 “Changes not staged for commit”部分(也就是 未暂存清单)看到
1.没有添加到暂存区的数据直接rm删除即可
2.已经添加到暂存区数据
git rm –cached database #将文件从git暂存区域的追踪列表移除(并不会删除当前工作目录内的数据文件)
git rm -f database #将文件数据从git暂存区和工作目录一起删除
如果删除之前修改过并且已经放到暂存区域的话,则必须要用强制删除选项 -f
- 重命名暂存区数据
1.没有添加到暂存区的数据直接mv/rename改名即可。
2.已经添加到暂存区数据
git mv README NOTICE
- 还原历史数据
Git服务程序中有一个叫做HEAD的版本指针,当用户申请还原数据时,其实就是将HEAD指针指向到某个特定的提交版本,但是因为Git是分布式版本控制系统,为了避免历史记录冲突,故使用了SHA-1计算出十六进制的哈希字串来区分每个提交版本,另外默认的HEAD版本指针会指向到最近的一次提交版本记录,而上一个提交版本会叫HEAD^,上上一个版本则会叫做HEAD^^,当然一般会用HEAD~5来表示往上数第五个提交版本。
git reset –hard hash
git reset –hard HEAD^ #→还原历史提交版本上一次
git reset –hard 3de15d4 #→找到历史还原点的SHA-1值后,就可以还原(值不写全,系统会自动匹配)
- 还原未来数据
什么是未来数据?就是你还原到历史数据了,但是你后悔了,想撤销更改,但是git log已经找不到这个版本了。
git reflog #→查看未来历史更新点
- 对比数据
git diff可以对比当前文件与仓库已保存文件的区别,知道了对README作了什么修改后,再把它提交到仓库就放⼼多了。
git diff README
- 记录每次更新到仓库
- 检查当前文件状态
$ git status
On branch master
nothing to commit, working directory clean
这说明你现在的工作目录相当干净。换句话说,所有已跟踪文件在上次提交后都未被更改过。 此外,上面的信息还表明,当前目录下没有出现任何处于未跟踪状态的新文件,否则 Git 会在这里列出来。 最后,该命令还显示了当前所在分支,并告诉你这个分支同远程服务器上对应的分支没有偏离。 现在,分支名是 “master”,这是默认的分支名。
- 跟踪新文件
$ git add README
$ git status
On branch master
Changes to be committed:
(use “git reset HEAD <file>…” to unstage)
new file: README
只要在 Changes to be committed 这行下面的,就说明是已暂存状态。 如果此时提交,那么该文件此时此刻的版本将被留存在历史记录中。
- 暂存已修改文件
现在我们来修改一个已被跟踪的文件。 如果你修改了一个名为 CONTRIBUTING.md 的已被跟踪的文件,然后运行 git status 命令,会看到下面内容:
$ git status
On branch master
Changes to be committed:
(use “git reset HEAD <file>…” to unstage)
new file: README
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: CONTRIBUTING.md
文件 CONTRIBUTING.md 出现在 Changes not staged for commit 这行下面,说明已跟踪文件的内容发生了变化,但还没有放到暂存区。 要暂存这次更新,需要运行 git add 命令。这是个多功能命令:可以用它开始跟踪新文件,或者把已跟踪的文件放到暂存区,还能用于合并时把有冲突的文件标记为已解决状态等。将这个命令理解为“添加内容到下一次提交中”而不是“将一个文件添加到项目中”要更加合适。
$ git add CONTRIBUTING.md
$ git status
On branch master
Changes to be committed:
(use “git reset HEAD <file>…” to unstage)
new file: README
modified: CONTRIBUTING.md
现在两个文件都已暂存,下次提交时就会一并记录到仓库。 假设此时,你想要在 CONTRIBUTING.md 里再加条注释, 重新编辑存盘后,准备好提交。
$ vim CONTRIBUTING.md
$ git status
On branch master
Changes to be committed:
(use “git reset HEAD <file>…” to unstage)
new file: README
modified: CONTRIBUTING.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: CONTRIBUTING.md
现在 CONTRIBUTING.md 文件同时出现在暂存区和非暂存区。 这怎么可能呢? 好吧,实际上 Git 只不过暂存了你运行 git add 命令时的版本, 如果你现在提交,CONTRIBUTING.md 的版本是你最后一次运行 git add 命令时的那个版本,而不是你运行 git commit 时,在工作目录中的当前版本。 所以,运行了 git add 之后又作了修订的文件,需要重新运行 git add 把最新版本重新暂存起来:
$ git add CONTRIBUTING.md
$ git status
On branch master
Changes to be committed:
(use “git reset HEAD <file>…” to unstage)
new file: README
modified: CONTRIBUTING.md
- 状态简览
git status 命令的输出十分详细,但其用语有些繁琐。 如果你使用 git status -s 命令或 git status –short 命令,你将得到一种更为紧凑的格式输出。 运行 git status -s ,状态报告输出如下:
$ git status -s
M README
MM Rakefile
A lib/git.rb
M lib/simplegit.rb
?? LICENSE.txt
新添加的未跟踪文件前面有 ?? 标记,新添加到暂存区中的文件前面有 A 标记,修改过的文件前面有 M 标记。 你可能注意到了 M 有两个可以出现的位置,出现在右边的 M 表示该文件被修改了但是还没放入暂存区,出现在靠左边的 M 表示该文件被修改了并放入了暂存区。 例如,上面的状态报告显示: README 文件在工作区被修改了但是还没有将修改后的文件放入暂存区,lib/simplegit.rb 文件被修改了并将修改后的文件放入了暂存区。 而 Rakefile 在工作区被修改并提交到暂存区后又在工作区中被修改了,所以在暂存区和工作区都有该文件被修改了的记录。
- 忽略文件
一般我们总会有些文件无需纳入 Git 的管理,也不希望它们总出现在未跟踪文件列表。 通常都是些自动生成的文件,比如日志文件,或者编译过程中创建的临时文件等。 在这种情况下,我们可以在工程根目录下创建一个名为 .gitignore 的文件,列出要忽略的文件模式。
Git 忽略规则匹配语法:
在 .gitignore 文件中,每一行的忽略规则的语法如下:
- 空格不匹配任意文件,可作为分隔符,可用反斜杠转义
- # 开头的文件标识注释,可以使用反斜杠进行转义
- ! 开头的模式标识否定,该文件将会再次被包含,如果排除了该文件的父级目录,则使用 ! 也不会再次被包含。可以使用反斜杠进行转义
- / 结束的模式只匹配文件夹以及在该文件夹路径下的内容,但是不匹配该文件
- / 开始的模式匹配项目跟目录
- 如果一个模式不包含斜杠,则它匹配相对于当前 .gitignore 文件路径的内容,如果该模式不在 .gitignore 文件中,则相对于项目根目录
- ** 匹配多级目录,可在开始,中间,结束
- ? 通用匹配单个字符
- [] 通用匹配单个字符列表
常用匹配示例:
- bin/: 忽略当前路径下的bin文件夹,该文件夹下的所有内容都会被忽略,不忽略 bin 文件
- /bin: 忽略根目录下的bin文件
- /*.c: 忽略 c,不忽略 build/cat.c
- debug/*.obj: 忽略 debug/io.obj,不忽略 debug/common/io.obj 和 tools/debug/io.obj
- **/foo: 忽略/foo, a/foo, a/b/foo等
- a/**/b: 忽略a/b, a/x/b, a/x/y/b等
- !/bin/run.sh: 不忽略 bin 目录下的 sh 文件
- *.log: 忽略所有 .log 文件
- php: 忽略当前路径的 config.php 文件
gitignore规则不生效
.gitignore只能忽略那些原来没有被track的文件,如果某些文件已经被纳入了版本管理中,则修改.gitignore是无效的。解决方法就是先把本地缓存删除(改变成未track状态),然后再提交:
git rm -r –cached .
git add .
git commit -m ‘update .gitignore’
- 提交更新
$ git commit #这种方式会启动文本编辑器以便输入本次提交的说明。
$ git commit -m “comment str” #将提交信息与命令放在同一行
$ git commit -a -m ‘added new benchmarks’ #跳过使用暂存区域
- 撤消操作
- 重新提交
有时候我们提交完了才发现漏掉了几个文件没有添加,或者提交信息写错了。 此时,可以运行带有 –amend 选项的提交命令尝试重新提交:
$ git commit –amend
这个命令会将暂存区中的文件提交。 如果自上次提交以来你还未做任何修改(例如,在上次提交后马上执行了此命令),那么快照会保持不变,而你所修改的只是提交信息。
例如,你提交后发现忘记了暂存某些需要的修改,可以像下面这样操作:
$ git commit -m ‘initial commit’
$ git add forgotten_file
$ git commit –amend
最终你只会有一个提交 – 第二次提交将代替第一次提交的结果。
- 取消暂存的文件
接下来的两个小节演示如何操作暂存区域与工作目录中已修改的文件。 这些命令在修改文件状态的同时,也会提示如何撤消操作。 例如,你已经修改了两个文件并且想要将它们作为两次独立的修改提交,但是却意外地输入了 git add * 暂存了它们两个。 如何只取消暂存两个中的一个呢? git status 命令提示了你:
$ git add *
$ git status
On branch master
Changes to be committed:
(use “git reset HEAD <file>…” to unstage)
renamed: README.md -> README
modified: CONTRIBUTING.md
在 “Changes to be committed” 文字正下方,提示使用 git reset HEAD <file>… 来取消暂存。 所以,我们可以这样来取消暂存 CONTRIBUTING.md 文件:
$ git reset HEAD CONTRIBUTING.md
Unstaged changes after reset:
M CONTRIBUTING.md
$ git status
On branch master
Changes to be committed:
(use “git reset HEAD <file>…” to unstage)
renamed: README.md -> README
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: CONTRIBUTING.md
注意:在调用时加上 –hard 选项可以令 git reset 成为一个危险的命令(译注:可能导致工作目录中所有当前进度丢失!),但本例中工作目录内的文件并不会被修改。 不加选项地调用 git reset 并不危险 — 它只会修改暂存区域。
- 撤消对文件的修改
如果你并不想保留对 CONTRIBUTING.md 文件的修改怎么办? 你该如何方便地撤消修改 – 将它还原成上次提交时的样子(或者刚克隆完的样子,或者刚把它放入工作目录时的样子)? 幸运的是,git status 也告诉了你应该如何做。 在最后一个例子中,未暂存区域是这样:
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: CONTRIBUTING.md
它非常清楚地告诉了你如何撤消之前所做的修改。 让我们来按照提示执行:
$ git checkout — CONTRIBUTING.md
$ git status
On branch master
Changes to be committed:
(use “git reset HEAD <file>…” to unstage)
renamed: README.md -> README
可以看到那些修改已经被撤消了。
注意:git checkout — [file] 是一个危险的命令,这很重要。 你对那个文件做的任何修改都会消失
- 远程仓库的使用
为了能在任意 Git 项目上协作,你需要知道如何管理自己的远程仓库。 远程仓库是指托管在因特网或其他网络中的你的项目的版本库。 你可以有好几个远程仓库,通常有些仓库对你只读,有些则可以读写。 与他人协作涉及管理远程仓库以及根据需要推送或拉取数据。 管理远程仓库包括了解如何添加远程仓库、移除无效的远程仓库、管理不同的远程分支并定义它们是否被跟踪等等。 在本节中,我们将介绍一部分远程管理的技能。
- 查看远程仓库
如果想查看你已经配置的远程仓库服务器,可以运行 git remote 命令。 它会列出你指定的每一个远程服务器的简写。 如果你已经克隆了自己的仓库,那么至少应该能看到 origin – 这是 Git 给你克隆的仓库服务器的默认名字:
$ git clone https://github.com/schacon/ticgit
Cloning into ‘ticgit’…
remote: Reusing existing pack: 1857, done.
remote: Total 1857 (delta 0), reused 0 (delta 0)
Receiving objects: 100% (1857/1857), 374.35 KiB | 268.00 KiB/s, done.
Resolving deltas: 100% (772/772), done.
Checking connectivity… done.
$ cd ticgit
$ git remote
origin
你也可以指定选项-v,会显示需要读写远程仓库使用的 Git 保存的简写与其对应的 URL。
$ git remote -v
origin https://github.com/schacon/ticgit (fetch)
origin https://github.com/schacon/ticgit (push)
koke git://github.com/koke/grit.git (fetch)
koke git://github.com/koke/grit.git (push)
- 添加远程仓库
运行 git remote add <shortname> <url> 添加一个新的远程 Git 仓库,同时指定一个你可以轻松引用的简写:
$ git remote
origin
$ git remote add pb https://github.com/paulboone/ticgit
$ git remote -v
origin https://github.com/schacon/ticgit (fetch)
origin https://github.com/schacon/ticgit (push)
pb https://github.com/paulboone/ticgit (fetch)
pb https://github.com/paulboone/ticgit (push)
现在你可以在命令行中使用字符串 pb 来代替整个 URL。 例如,如果你想拉取 Paul 的仓库中有但你没有的信息,可以运行 git fetch pb:
$ git fetch pb
remote: Counting objects: 43, done.
remote: Compressing objects: 100% (36/36), done.
remote: Total 43 (delta 10), reused 31 (delta 5)
Unpacking objects: 100% (43/43), done.
From https://github.com/paulboone/ticgit
* [new branch] master -> pb/master
* [new branch] ticgit -> pb/ticgit
现在 Paul 的 master 分支可以在本地通过 pb/master 访问到 – 你可以将它合并到自己的某个分支中,或者如果你想要查看它的话,可以检出一个指向该点的本地分支。
- 远程仓库的移除与重命名
如果想要重命名引用的名字可以运行 git remote rename 去修改一个远程仓库的简写名。
$ git remote rename pb paul #将 pb 重命名为 paul
这同样也会修改你的远程分支名字。那些过去引用pb/master的现在会引用paul/master
git remote rm paul #移除一个远程仓库