一、GIt的安装
(1)Linux上安装方法
sudo yum install git-all
或者
yum install git-all
(2)Ubuntu系统安装方法
sudo apt-get install git-all
或者
apt-get install git-all
(3)Mac上的安装方法
brew install git
(4)Windows上安装方法
进入GIt官网下载地址:https://git-scm.com/downloads,选择Windows版下载后直接点击安装即可
二、Git的配置
(1)配置个人信息
安装好Git后的第一件事就是设置用户名和电子邮件地址。这一步非常重要,因为Git的每一次提交都会用到这些已经设置好的信息。
设置用户名:
git config --global user.name "your name"
设置email:
git config --global user.email "your email"
如果使用--global选项,那么只需要设置一次就可以了,之后不管在系统中执行什么操作,Git都会使用这些已经设置好得信息。如果你想在某个项目中使用不同的用户名或电子邮件地址,可以在项目中使用不带--global选项的命令。
(2)配置个人编辑器
设置好身份信息后就可以配置默认的文本编辑器了。当Git需要输入信息时就会用到这个编辑器。如果没有配置,Git会使用系统默认的编辑器。
如果想使用不同的文本编辑器,比如Emacs,可以执行以下命令进行配置。
git config --global core.editor emacs
在Windows系统中,如果想使用不同的文本编辑器,比如Notepad++,可以执行以下操作。
在x86系统上:
git config --global core.editor "'C:/Program Files(x86)/Notepad++/notepad++.exe' -multiInst -nosession"
在x64系统上:
git config --global core.editor "'C:/Program Files/Notepad++/notepad++.exe' -mutiInst"
(3)查看GIt配置信息
如果你想查看你的设置以及Git的默认设置信息,可以通过执行
git config --list 或 git config -l
命令进行查看。若你想查看具体的某个配置,可以使用以下命令来查看Git中当前某个键的值
$ git config <key>
例如:
$ git config alias.d
diff
三、Git的常用命令
(1)git init ———— 在现有目录中初始化Git仓库
要想在Git中对现有项目进行跟踪管理(初始化),只需要进入项目目录并输入:
git init
这会创建一个名为.git的子目录。这个目录中包含了构成GIt仓库的所有必需文件。但此刻Git并未跟踪项目中的任何文件。
(2)git add
2.1、跟踪新的文件
可以使用git add 命令让Git开始跟踪新的文件。
跟踪某个文件:
git add <filename>
跟踪整个目录(常用):
git add .
git add 命令接受一个文件或目录的路径名作为参数。如果提供的参数是目录,该命令会递归添加该目录下的所有文件。
2.2、暂存已修改的文件
若我们修改了一个已跟踪的文件,此时使用git status命令,会看到修改的文件在一个输出信息:“Changes not staged for commit”(已更改但未添加到暂存区)的区域中,这表示处于跟踪状态的文件在工作目录下已被修改,但尚未添加到暂存区。要想要暂存这些文件,需要执行git add命令。
2.3、将冲突文件标记为已解决
当我们提交代码时有冲突,解决相应的冲突文件后,若想再次提交,需要使用git add 命令将该冲突文件标记为解决,然后再次提交。
所以,把git add命令看成“添加内容到下一次提交中”而不是“把这个文件加入到项目中”,更有助于理解该命令。
(3)git status ————查看当前文件状态
检测文件所处的状态主要工具是git status命令。在Git中,文件可以处于以下状态之一:一提交(committed)、已修改(modified)和已暂存(staged)。已提交表示数据已被安全存入本地仓库中。已修改表示已经修改了文件,但尚未提交到本体仓库。已暂存表示对已修改文件的当前版本做出了标识并将其加入到下一次要提交的快照中。
在工作目录下的每一个文件都处于两种状态之一:已跟踪(tracked)或未跟踪(untracked)。已跟踪的文件指的是上一次快照中包含的文件。这些文件又可以分为为修改、已修改或已暂存三种状态。而未跟踪的文件则是工作目录中除去已跟踪文件之外的所有文件,也就是既不在上一次快照中,也不在暂存区中的文件。例如,当你刚刚完成仓库克隆时,所有文件的状态都是已跟踪且为修改的。
虽然git status命令的输出信息很全面,但也会比较冗长。可以使用以下命令来查看简洁信息:
git status -s 或
git status --short
例如一些输出信息如下:
$ git status -s
M README
MM Rakefile
A lib/git.b
M lib/simple.rb
?? LICENSE.txt
其中未被跟踪的新文件旁边会有一个??标记,已暂存的新文件会有A标记,而已修改的文件则会有一个M标记,已修改并添加到暂存区,之后又被修改过,因此暂存区和工作区都包含了该文件的修改,此类文件有一个MM标记,例如Rakefile文件。
(4)git diff ————查看已暂存和未暂存的变更
如果你想知道修改的具体的内容,而不仅仅是你更改了那些文件,这时可以使用git diif命令。git diff 可以用来解决两个问题:哪些变更还没有被暂存?哪些已暂存的变更正待提交?尽管git status也可以通过列举文件名的方式大致回答上述问题,但git diff则会显示出你具体添加、修改和删除了哪些信息。
如果你要查看未添加到暂存区的变更,直接输入不加参数的git diff命令:示例:
$ git status
On branch dev
Your branch is up to date with 'origin/dev'.
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
bogon:jack-springcloud qinshichang$ git diff
diff --git a/README.md b/README.md
index 3b0a5d8..e9a9ea1 100644
--- a/README.md
+++ b/README.md
bogon:jack-springcloud qinshichang$ git status
On branch dev
Your branch is up to date with 'origin/dev'.
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
bogon:jack-springcloud qinshichang$ git diff
diff --git a/README.md b/README.md
index 3b0a5d8..e9a9ea1 100644
--- a/README.md
+++ b/README.md
@@ -1 +1 @@
34y32s1234y32s1234y32s1234y32s1234y32s1234y32s1234y32s1234y32s1234y32s1234y32s1234y32s1234y32s1234y32s1234y32s
+12345678
git diff命令会将当前工作目录下的内容与暂存区的内容作比较。对比的结果就显示了有哪些还有没有暂存的变更。
如果你想查看有哪些已暂存的内容会进入下一次提交,可以使用git diff --staged命令或git diff --cached命令。这条命令会将暂存区的变更与上一次提交的内容相比较。例如将上述的“修改还没有提交到暂存区”的README.md文件使用git add 命令将该文件放到暂存区,然后使用git diff --stage查看,相关操作如下:
$ git add README.md
$ git status
On branch dev
Your branch is up to date with 'origin/dev'.
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)
new file: README.md
$ git diff --staged
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..e9a9ea1
--- /dev/null
+++ b/README.md
@@ -0,0 +1 @@
+12345678
\ No newline at end of file
请注意,使用git diff本身并不会显示自从上一次提交以来的所有的变更,而只是显示出还未进入暂存区的哪些变更。如果你已经把所有的变更添加到了暂存区,gif diff不会有任何的输入。
如果你暂存了一个文件之后又对它进行了修改,可以使用git diff命令来查看已暂存和为暂存的变更。
(5)git commit ———— 提交变更
现在你的暂存区已经准备好了,可以提交了。请记住所有为暂存的变更都不会进入到提交的内容中,这包括在编辑之后没有执行git add命令添加到暂存区的新建或者修改过的文件。最简单的提交方式就是执行git commit命令:
$ git commit
执行这条命令后会打开你所选择的文本编辑器。(默认编辑器可以使用git config --global core.editor命令进行配置)。文本编辑器会显示以下文本(以Emacs为例)
可以看出,默认的提交信息会包括注释掉的git status命令的最新输出结果,在最上边还有一个空行。你既可以删除这些注释并输入自己的提交信息,也可以保留这些注释,以帮助你记住提交的具体内容。(若需要记下更详细的更改记录,可以使用git connit 加上-v参数。这样会把这次提交的差异对比显示在文本编辑器中,让你可以看到要提交的变更。)当你退出编辑器时,Git会移除注释信息和差异对比,把剩下的提交信息记录到所创建的提交中。
完成提交还有一种方式,那就是直接在命令行键入要提交的信息。这需要给git commit命令加上一个-m选项。例如
$ git commit -m "README File commit"
[dev 24b8e91] README File commit
2 files changed, 3 insertions(+)
create mode 100644 README.md
create mode 100644 README.txt
(6)git commit -a ———— 跳过暂存区直接提交
如果你想要跳过暂存区提交,Git提供了一个快捷方式。给git commit命令传入-a选项,就可以让Git自动把已跟踪的所有文件添加到暂存区,然后提交,这样你就不用再执行git add命令了。例如
$ vim 123.txt
$ echo "error" >> README.txt
$ git commit -a -m "跳过暂存区执行提交"
[dev 29c07bd] 跳过暂存区执行提交
1 file changed, 1 insertion(+)
注意在上面的例子中,提交前不需要再执行git add来添加123.txt和README.txt文件了。
(7)git rm ———— 移除文件
要从Git中移除某个文件,你需要把它先从跟踪文件列表中移除(确切地说,是从暂存区中移除),然后提交。git rm会帮助你完成这些操作,另外该命令还会把文件从工作目录中移除,这样下一次你就不会在未跟踪文件列表中看到这些文件了。
如果你只是简单地把文件从工作目录中移除,而没有使用git rm,那么在执行git status时会看到文件出现在“Change not staged for commit”区域(也就是为暂存区):
# 新增1234.txt文件
$ echo "123" >> 1234.txt
# 添加到暂存区
$ git add .
$ git status
On branch dev
Your branch is ahead of 'origin/dev' by 2 commits.
(use "git push" to publish your local commits)
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)
new file: 1234.txt
# 直接删除文件
$ rm 1234.txt
$ git status
On branch dev
Your branch is ahead of 'origin/dev' by 2 commits.
(use "git push" to publish your local commits)
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)
new file: 1234.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: 1234.txt
如果你这时候执行git rm,Git才会把文件的移除状态记录到暂存区:
$ git rm 1234.txt
rm '1234.txt'
$ git status
On branch dev
Your branch is ahead of 'origin/dev' by 2 commits.
(use "git push" to publish your local commits)
nothing to commit, working tree clean
下次提交的时候,这个文件就不存在了,也不会被Git跟踪管理。如果你更改了某个文件,并已经把它加入到索引中(已暂存),要想要让Git移除它就需要使用-f选项强制删除。这是为了防止没有被记录到快照中的数据被意外删除而设立的安全特性,因为这样的数据被意外删除后Git无法恢复。
还有一种情况就是把文件保留在工作目录,但从暂存区中移除该文件。换句话说,你也许希望将文件保留在硬盘上,但是不想让Git对其进行跟踪管理。如果你忘了向.gitignore文件中添加相应的规则,不小心把一个较大的日志文件或者编译生成的.a文件添加进去,以下做法尤其有用。只需使用--cached选项即可:例如
$ git rm --cached README
你可以将文件、目录和文件的glob模式传递给git rm 命令。这意味着你可以像以下这样:将log目录下.log文件删除
从工作空间移除:
$ git rm log/\*.log
将文件保留在工作空间,但不让Git跟踪管理
$ git rm --cached log/\*.log
请注意在*前面的反斜杠(\)是必需的,这是因为shell和Git先后都要处理文件名扩展。或者也可以像下面这样:
$ git rm \*~
这条命令会移除所有以~结尾的文件。
(8)git mv ———— 移动文件(或重命名文件)
在Git中可以使用如下命令重命名文件:
$ git mv README.txt hello.txt
$ git status
On branch dev
Your branch is ahead of 'origin/dev' by 2 commits.
(use "git push" to publish your local commits)
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)
renamed: README.txt -> hello.txt
其实在执行git mv README.txt hello.txt命令,相当于执行了下面的三条命令:
$ mv README.txt hello.txt
$ git rm README.txt
$ git add hello.txt
不管你是使用Git的mv命令,还是直接给文件改名,Git都可以推断出这是重命名操作。唯一的区别是使用git mv只需要输入一条命令而不是三条,所以会比较方便。
(9)git log ———— 查看提交历史
在完成了几次提交,或者克隆了一个已有提交历史的仓库之后,你可能想要查看提交历史记录。可以使用git log命令来实现。这是一个基础而又强大的命令。
例如执行git log命令
$ git log
commit 29c07bd7e7172244bdae3b8d28e747fc15933834 (HEAD -> dev)
Author: 纳滋 <128^_^80@qq.com>
Date: Tue Oct 29 00:37:42 2019 +0800
跳过暂存区执行提交
commit 24b8e914643993735964ed8d97c5d58febef63c4
Author: 纳滋 <128^_^80@qq.com>
Date: Tue Oct 29 00:30:52 2019 +0800
README File commit
commit 29c07bd7e7172244bdae3b8d28e747fc15933834 (HEAD -> dev)
Author: 纳滋 <128^_^80@qq.com>
Date: Tue Oct 29 00:37:42 2019 +0800
跳过暂存区执行提交
commit 24b8e914643993735964ed8d97c5d58febef63c4
Author: 纳滋 <128^_^80@qq.com>
Date: Tue Oct 29 00:30:52 2019 +0800
README File commit
默认不叫参数的情况下,git log会按照时间顺序列出仓库中所有的提交,其中最新的提交显示在最前面。每一个提交都会列出它的SHA-1校验和、作者的姓名和邮箱、提交日期以及提交信息。
git log有很多不同的选项,可以直观地显示所需内容。最有用的一个选项是-p,它会显示出每次提交所引入的差异。你还可以加上-n参数,n代表数字,例如-2表示只输出最近两次提交。例如:
$ git log -p -1
commit 29c07bd7e7172244bdae3b8d28e747fc15933834 (HEAD -> dev)
Author: 纳滋 <128^_^80@qq.com>
Date: Tue Oct 29 00:37:42 2019 +0800
跳过暂存区执行提交
diff --git a/README.txt b/README.txt
index 0f2521c..9d8676a 100644
--- a/README.txt
+++ b/README.txt
@@ -1,2 +1,3 @@
qwert
# test line
+error
(END)
可以使用--stat选项来查看每个提交的简要统计信息:
$ git log --stat -1
commit 29c07bd7e7172244bdae3b8d28e747fc15933834 (HEAD -> dev)
Author: 纳滋 <128^_^80@qq.com>
Date: Tue Oct 29 00:37:42 2019 +0800
跳过暂存区执行提交
README.txt | 1 +
1 file changed, 1 insertion(+)
使用--stat选项会列出每个提交的如下信息:改动的问价列表、共有多少个文件被改动以及文件里新增多少行和删除行。另位在最后还会输出总计信息。
另位一个颇为有用的选项是--perty,它可以更改日志输出信息的默认格式。Git有一些预置的格式可供你选择。例如,在浏览大量的提交时,online格式选项很有用,它可以在每一行中显示一个提交。除此之外,short、full和fuller格式选项会分别比默认输出减少或增加一些输出信息。例如:
# oneline模式
$ git log --pretty=oneline
29c07bd7e7172244bdae3b8d28e747fc15933834 (HEAD -> dev) 跳过暂存区执行提交
24b8e914643993735964ed8d97c5d58febef63c4 README File commit
9e451f479318c5c24fa96ffbf3133d7ac9037cee (origin/dev) 新增删除用户方法在dev分支
8eb284ce002237f3ab017af0d6fb6bf6d41df4d0 git branch test
8a0d578aad4a024d3e17d5583c0ca93a6aae893d (master) initial jack-springcloud for gitlab repository
# short模式
$ git log --pretty=short
commit 29c07bd7e7172244bdae3b8d28e747fc15933834 (HEAD -> dev)
Author: 纳滋 <128^_^80@qq.com>
跳过暂存区执行提交
commit 24b8e914643993735964ed8d97c5d58febef63c4
Author: 纳滋 <128^_^80@qq.com>
README File commit
commit 9e451f479318c5c24fa96ffbf3133d7ac9037cee (origin/dev)
Author: 纳滋 <128^_^80@qq.com>
# full模式
$ git log --pretty=full
commit 29c07bd7e7172244bdae3b8d28e747fc15933834 (HEAD -> dev)
Author: 纳滋 <128^_^80@qq.com>
Commit: 纳滋 <128^_^80@qq.com>
跳过暂存区执行提交
# fuller模式
$ git log --pretty=fuller
commit 29c07bd7e7172244bdae3b8d28e747fc15933834 (HEAD -> dev)
Author: 纳滋 <1281509180@qq.com>
AuthorDate: Tue Oct 29 00:37:42 2019 +0800
Commit: 纳滋 <1281509180@qq.com>
CommitDate: Tue Oct 29 00:37:42 2019 +0800
跳过暂存区执行提交
最值得注意的选项是format,它允许你指定自己的输出格式。这样的输出特别有助于机器解析,因为你可以明确输出格式,其结果不会随着Git软件版本而改变。例如:
$ git log --pretty=format:"%h - %an, %ar : %s"
29c07bd - 纳滋, 24 hours ago : 跳过暂存区执行提交
24b8e91 - 纳滋, 24 hours ago : README File commit
9e451f4 - 纳滋, 5 days ago : 新增删除用户方法在dev分支
8eb284c - 纳滋, 5 days ago : git branch test
8a0d578 - 纳滋, 5 days ago : initial jack-springcloud for gitlab repository
以下列举了 git log --pretty=format命令的一些有用选项
%H 提交对象(commit)的完整哈希字串
%h 提交对象的简短哈希字串
%T 树对象(tree)的完整哈希字串
%t 树对象的简短哈希字串
%P 父对象(parent)的完整哈希字串
%p 父对象的简短哈希字串
%an 作者(author)的名字
%ae 作者的电子邮件地址
%ad 创作日期(可以用 -date= 选项定制格式)
%ar 相对于当前日期的创作日期
%cn 提交者(committer)的名字
%ce 提交者的电子邮件地址
%cd 提交日期
%cr 相对于当前日期的提交日期
%s 提交说明
oneline和format选项如果与log命令的另一个选项--graph一起使用,就可以发挥更大的作用。具体来说,--graph选项会用ASCLL字符形式的简单图表来显示Git分支合并历史。例如:
$ git log --pretty=format:"%h %s" --graph
* 0e3e8a2 Merge branch 'dev' into 'master'
|\
| * 29c07bd 跳过暂存区执行提交
| * 24b8e91 README File commit
* | 8a8d202 Merge branch 'dev' into 'master'
|\ \
| |/
| * 9e451f4 新增删除用户方法在dev分支
| * 8eb284c git branch test
|/
* 8a0d578 initial jack-springcloud for gitlab repository
git log除了有输出格式的选项之外还有一些其他有用的限制选项,这些选项可以只显示部分提交。我想你已经见过一个选项了,也就是-n选项。-n选项可以用来显示最新的n次提交,其中n是整数。不过这个选项在Git实际中并不常用,应为默认下Git的所有输出会通过管道机制输入给分页程序(pager),使其一次只显示一页内容。
与上述选项不同,像--since和--untill这样按时间限制输出的选项是十分有用的。例如,下面的命令会列举出最近两周内的所有提交记录:
$ git log --since=2.weeks
commit 0e3e8a2b2b04dc1ca9785ac01ec9562eec28b294 (HEAD -> master, origin/master)
Merge: 8a8d202 29c07bd
Author: 纳滋 <128^_^80@qq.com>
Date: Wed Oct 30 00:51:17 2019 +0800
Merge branch 'dev' into 'master'
Dev
See merge request tomJerry/jack-springcloud!2
这条命令可以使用不同的时间形式,比如使用像“2019-10-28”这样的某个具体时间,或者类似“2 years 1 day 3 minutes ago”(两年零一天三分钟前)这样的相对时间。
你还可以按照某个搜索条件过滤提交列表。--author选项允许你只查询某个作者的提交,--grep选项则能让你搜索信息中的关键字(如果要同时指定author和grep选项,则需要添加--all-metch参数,否则Git会列出所有符合任何单一条件的提交)。
另一个非常有用的过滤选项是-S选项,它后面需要接上一个字符串参数。这个选项只输出那些添加或者删除指定字符串的提交。举个例子,如果你想查找添加或删除了特定函数引用的最近一次提交,可以执行以下命令:
$ git log -SwipeUserByUserId
commit 9e451f479318c5c24fa96ffbf3133d7ac9037cee
Author: 纳滋 <1281509180@qq.com>
Date: Fri Oct 25 00:08:29 2019 +0800
新增删除用户方法在dev分支
#注意:wipeUserByUserId是函数名称
最后一个很有用的git log过滤选项是文件路径。如果你指定了一个目录名或者文件名,就可以只输出更改了指定文件的那些提交。这个选项总是作为最后一个命令选项出现,通常需要在之前加两个短横线(--)来将路径和其他选项分隔开。
(10)git commit --amend ———— 撤销操作
在任何时候,你都有可能撤销之前的操作。请需要注意,在Git中有些撤销操作是不可逆的,所以需要务必小心。撤销常用的场景是提交之后才发现自己忘记添加某些文件,或者写错了提交信息。如果这时你想要尝试重新提交,可以使用git commit命令的--amend选项。
$ git commit --amend
上述命令会提交暂存区的内容。如果你在上次提交之后并没有做出任何改动(比如你在上次提交之后立即执行上述命令),那么你提交的快照就不会发生变化,但你可以改动提交信息。
和之前的提交一样,这次也会启动提交信息编辑器,有所不同的是打开编辑器中会显示上次提交的信息。你可以像之前一样编辑,保存后就会覆盖之前的提交信息。
举个例子,如果你提交之后才发先提交是编写的提交信息有错误,你可以执行类似下面的操作。
$ git commit -m "commit hello.txt file"
[master 3c22184] commit hello.txt file
1 file changed, 5 insertions(+)
create mode 100644 hello.txt
$ git commit --amend
hint: Waiting for your editor to close the file...
上述操作最终只是产生了一次提交,因为第二次提交命令修正了第一次的提交结果。
(11)git reset ———— 撤销已暂存的文件
假如你更改了两个文件,想要分两次提交,且不小心键入了git add *,把这两个文件都添加到了暂存区。这时你该如何把它们从暂存区移出呢?其实git status命令会提示你该如何做:
$ git status
On branch master
Your branch is up to date with 'origin/master'.
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)
new file: hello.txt
在“Changes to be commited”正下方显示的提示是“使用git reset HEAD <file> ......命令把文件移出暂存区“。所以我们就用提示的方法把hello.txt文件移出暂存区:
$ git reset HEAD hello.txt
$ git status
On branch master
Your branch is up to date with 'origin/master'.
Untracked files:
(use "git add <file>..." to include in what will be committed)
hello.txt
nothing added to commit but untracked files present (use "git add" to track)
执行git reset命令后在使用git status命令查看,发现文件确实已修改到为暂存的状态。
注意:尽管git reset 加上--hard参数时很危险,但是如果你使用上述例子中的命令操作,工作目录中的文件就不会被改动。也就是说,执行不加选项的git reset是安全的,它只是更改暂存区。
(12)git checkout -- <file> 撤销对文件的修改
如果你在对某个暂存区的文件修改后发现已不再需要之前所做得修改,这时该怎么办?如何轻松地撤销修改并把文件恢复到提交时的状态(或者刚克隆仓库后的状态,或是一开始它在工作目录中的状态)?幸运的是,git status这次也会告述你该如何做。例如:
$ git status
On branch master
Your branch is ahead of 'origin/master' by 1 commit.
(use "git push" to publish your local commits)
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: hello.txt
no changes added to commit (use "git add" and/or "git commit -a")
在上述的输出结果中明确概述我们使用"git checkout -- <file>..." 放弃工作目录中的更改。我们照着它说的做:
$ git checkout -- hello.txt
$ git status
On branch master
Your branch is ahead of 'origin/master' by 1 commit.
(use "git push" to publish your local commits)
nothing to commit, working tree clean
可以看出,之前的修改已经恢复了。需要注意的是,git checkout -- <file> 是一个危险的命令。执行该命令后,任何对[file]的修改都会丢失,应为上述命令使用之前版本的文件进行覆盖。除非你确信不需要这些修改,否则不要使用这个命令。
请记住,在Git中提交的任何变更几乎总是可以进行恢复。哪怕是在已删除的分支上提交或被--amend覆盖的提交,都可以进行恢复。但是,任何未提交过的变更一旦丢失,久很可能再也无法恢复了。
四、GIt远程仓库的使用
远程仓库指的是在互联网或其他网络上托管的项目版本仓库。你可以拥有多个远程仓库,而对其中每个仓库,你可能或拥有不同的权限。要同别协作,就需要管理这些仓库,在需要分享工作成果时,向其推送数据,或从中拉取数据。
(1)克隆现有仓库
如果你需要获取现有仓库的一份副本,你可以使用git clone [url] 命令。git clone命令对服务器仓库的几乎所有数据进行完整复制,而不只是复制当前工作目录。git clone会默认从服务器上把整个项目历史中的每个文件的所有历史版本都拉取下来。实际上,如果你服务器磁盘损坏,你通常可以使用任何客户端计算机上的Git仓库副本恢复服务器(一些文件可能会丢失)。
克隆仓库需要使用git clone [url] 命令。
(2)显示远程仓库
要查看已经设置了那些远程仓库,请使用git remote命令。该命令会列出每个远程仓库的简短名称。在克隆某个仓库后,你至少可以看到一个名为origin的远程仓库,这是Git给克隆源服务器取的默认名称。
$ git remote
origin
你也可以使用-v参数,这样会显示出Git存储的每个远程仓库对应的URL:
$ git remote -v
origin git@git.lug.ustc.edu.cn:tomJerry/jack-springcloud.git (fetch)
origin git@git.lug.ustc.edu.cn:tomJerry/jack-springcloud.git (push)
如果你有不止一个远程仓库,上面的命令会把它们都列出来。
(3)添加远程仓库
要添加一个远程仓库,并给他取一个简短的名称以便引用,可以使用git remote add [shortname] [url] 命令:
$ git remote add cloudwork git@git.lug.ustc.edu.cn:tomJerry/cloudwork.git
$ git remote
cloudwork
origin
$ git remote -v
cloudwork git@git.lug.ustc.edu.cn:tomJerry/cloudwork.git (fetch)
cloudwork git@git.lug.ustc.edu.cn:tomJerry/cloudwork.git (push)
origin git@git.lug.ustc.edu.cn:tomJerry/jack-springcloud.git (fetch)
origin git@git.lug.ustc.edu.cn:tomJerry/jack-springcloud.git (push)
(3)从远程仓库获取和拉取数据
要从远程仓库获取数据,可以执行:
git fetch [remote-name]
这条命令会从远程仓库中获取所有仓库中没有的数据。在执行上述命令后,你就可以在本地引用远程仓库包含的所有分支,并可以在任何时候合并并检查这些分支。
当你克隆仓库时,克隆命令会自动添加远程仓库地址并取名"origin"。当随后执行git fetch origin时,会获取上一次克隆(或获取)之后被推送到服务端的新增的变更数据。请注意,git fetch命令只会把数据拉取到本地仓库,然而它并不会将这些数据合并到本地工作成果中,也不会修改当前工作目录下的任何数据。在准备好后,需要手动将这些数据合并到本地内容中。
如果你有跟踪着某个远程分支的本地分支,可以使用git pull命令来自动获取远程分支的数据,并将远程分支合并入当前本地分支。
(4)将数据推送到远程仓库
当你需要与他人分享开发成果时,就需要把变更推送到远程仓库去。用到的命令很简单:git push [remote-name] [branch-name]。如果你想把本地的master分支推送到远程的origin服务器上,那么可以执行以下命令:
$git push origin master
上述命令能够正常工作的前提必要条件是必须拥有克隆下来远程仓库的写权限,并且克隆后没有任何其他人向远程仓库推送过数据。如果别人和你都克隆了这个仓库,而他先推送,你后推送,那么你的推送就会被直接拒接。你必须先拉取(git pull)别人的变更,将其合并到你的工作空间中,然后才可以推送。
(5)检查远程仓库
要查看关于某一个远程仓库的更多信息,可以使用git remote show [remote-name]命令。如果给该命令提供一个仓库的短名称,比如origin,就会看到如下输出:
$ git remote show origin
* remote origin
Fetch URL: git@git.lug.ustc.edu.cn:tomJerry/jack-springcloud.git
Push URL: git@git.lug.ustc.edu.cn:tomJerry/jack-springcloud.git
HEAD branch: master
Remote branches:
dev tracked
master tracked
test-branch tracked
Local branches configured for 'git pull':
dev merges with remote dev
master merges with remote master
test-branch merges with remote test-branch
Local refs configured for 'git push':
dev pushes to dev (up to date)
master pushes to master (fast-forwardable)
test-branch pushes to test-branch (up to date)
这条命令会输出一些很有帮助的信息,比如告述你master分支上执行git pull会获取到所有的远程引用,然后自动合并入master。它还显示了拉取下来的所有远程引用信息。当你大量使用Git时,git remote show可能会给出非常多的信息。例如,当你在本地某个分支执行git push时,会推送到远程的那个分支上去。另外,它还会显示服务器上有哪些本地还没有的远程分支,那些本地分支对应的远程分支已被删除,执行git pull时那些分支会自动合并更新的变更。
(6)删除和重命名远程仓库
可以使用git remote rename来重命名远程仓库。如果想要把origin重命名为origin-master,可以使用git remote rename命令来实现,如下所示:
$ git remote rename origin origin-master
$ git remote
origin-master
值得一提的是,上述操作也会更改远程分支的名称。先前的origin/master分支现在变成了origin-master/master。
有时出于某些原因,需要删除某个远程仓库地址,比如当你迁移了某个服务器地址,或者不再使用某一个仓库镜像,可以使用git remote rm命令,如下所示。
$ git remote rm origin
$ git remote
五、标记
就像大多数版本控制系统一样,Git可以把特定的历史版本标记为重要版本。其典型应用场景是标出发布版本(v1.0等)。
(1)列举标记
在Git,列举标记操作很简单,只需要键入git tag即可:
$ git tag
这条命令会按照字母顺序列出所有的标签。列举的顺序先后和标签的重要性无关。你还可以按照某个特定的匹配模式搜索标签,例如你想查看v1.8.5*系列的标记版本,可以执行以下命令:
$ git tag -l "v1.8.5*"
(2)创建标签
Git使用的标签主要有两种类型:轻量(lightweight)标签和注释(annotated)标签。
轻量标签很像一个不变的分支————它只是一个指向某次提交的指针。
注释标签则会作为完整的对象存储在Git数据库中。Git会计算其校验和,除此之外还包含其他信息,比如标记者(tagger)的名字、邮箱地址和标签的创建时间,还有标记信息(tagging message),另位还可以使用GNU Privacy Guard(GPG)对它们进行签名和验证。一般推荐创建注释标签。
(3)注释标签
创建注释标签很简单,只需执行带有-a选项的tag命令即可:
$ git tag -a v1.0.0v -m "my version 1.0.0"
$ git tag
v1.0.0
-m选项指定了标记信息,它会伴随标签一起存储。如果你没有为注释标签标记信息,Git会打开文本编辑器以便你输入。
执行git show命令可以看到标签数据以及对应的提交:
$ git show v1.0.0
tag v1.0.0
Tagger: 纳滋 <1281509180@qq.com>
Date: Thu Oct 31 01:15:11 2019 +0800
my version 1.0.0
(4)轻量标签
另一种用来标记提交的方法是使用轻量标签。这种标签基本上就是把提交的校验和保存到文件中,除此之外,不包含其他任何信息。创建一个轻量轻量标签时不需要使用-a、-s或-m选项:
$ git tag v1.0.0-lw
$ git tag
v1.0.0
v1.0.0-lw
如果你现在在这个标签上使用git show命令,除了提交信息外,不会看到别的标签信息。
$ git show v1.0.0-lw
commit 0e3e8a2b2b04dc1ca9785ac01ec9562eec28b294 (HEAD -> test-branch, tag: v1.0.0-lw, tag: v1.0.0, origin/test-branch, origin/master)
Merge: 8a8d202 29c07bd
Author: 纳滋 <128^_^80@qq.com>
Date: Wed Oct 30 00:51:17 2019 +0800
Merge branch 'dev' into 'master'
Dev
(5)补加标签
你可以在给之前的提交添加标签,假设你的提交历史如下:
$ git log --pretty=oneline
0e3e8a2b2b04dc1ca9785ac01ec9562eec28b294 (HEAD -> test-branch, tag: v1.0.0-lw, tag: v1.0.0, origin/test-branch) Merge branch 'dev' into 'master'
29c07bd7e7172244bdae3b8d28e747fc15933834 (origin/dev, dev) 跳过暂存区执行提交
24b8e914643993735964ed8d97c5d58febef63c4 README File commit
8a8d2020147872318a2e62e9b004e4c7fce126a3 Merge branch 'dev' into 'master'
9e451f479318c5c24fa96ffbf3133d7ac9037cee 新增删除用户方法在dev分支
8eb284ce002237f3ab017af0d6fb6bf6d41df4d0 git branch test
8a0d578aad4a024d3e17d5583c0ca93a6aae893d initial jack-springcloud for gitlab repository
现在你可以使用git tag -a "version mseeage" commit_id 给某次提交添加标签,如下:
$ git tag -a v1.0.1 -m "README file commit" 24b8e914643993735964ed8d97c5d58febef63c4
$ git tag
v1.0.0
v1.0.0-lw
v1.0.1
$ git show v1.0.1
tag v1.0.1
Tagger: 纳滋 <12^_^80@qq.com>
Date: Thu Oct 31 22:22:56 2019 +0800
(7)共享标签
默认情况下,git push命令不会把标签传输到远程服务器上。在创建了标签之后,你必须明确地将标签推送到共享服务器上。这个过程有点像推送分支,对应的命令是git push origin [tagname]。
$ git push origin v1.0.0
Enumerating objects: 1, done.
Counting objects: 100% (1/1), done.
Writing objects: 100% (1/1), 167 bytes | 167.00 KiB/s, done.
Total 1 (delta 0), reused 0 (delta 0)
To git.lug.ustc.edu.cn:tomJerry/jack-springcloud.git
* [new tag] v1.0.0 -> v1.0.0
如果你有很多标签需要一次性推送,可以使用git push命令的--tags选项。这会把所有的服务器上还没有的标签都推送过去:
$ git push --tags
Enumerating objects: 1, done.
Counting objects: 100% (1/1), done.
Writing objects: 100% (1/1), 173 bytes | 173.00 KiB/s, done.
Total 1 (delta 0), reused 0 (delta 0)
To git.lug.ustc.edu.cn:tomJerry/jack-springcloud.git
* [new tag] v1.0.0-lw -> v1.0.0-lw
* [new tag] v1.0.1 -> v1.0.1
执行完上述命令后,如果其他人此时对仓库执行克隆或拉取操作,他们也能够得到所有的标签。
(8)检出标签
你是无法在Git中真正检出一个标签的,这是因为标签是无法移动的。如果想将某个版本的仓库放入像是标签的工作目录中,可以是用git checkout -b [branchname] [tagname]在特定标签上创建一个新的分支。
(9)Git别名
如果你键入的Git命令不完整,Git是不会自动推断并补全命令。虽然如此,但是如果你不想每次都费力键入完整的Git命令,那么可以通过git config 设置每个Git命令的别名。下面是一些你可能想要设置的别名:
$ git config --global alias.co checkout
$ git config --global alias.br branck
$ git config --global alias.ci commit
$ git config --global alias.st status
目前Git也会默认配置一些别名信息,可以使用git onfig -l 或git config --list来查看:
$ git config -l
alias.au=!git add -u . && git status
alias.aa=!git add . && git add -u . && git status
alias.c=commit
alias.cm=commit -m
alias.ca=commit --amend
alias.ac=!git add . && git commit
alias.acm=!git add . && git commit -m
alias.l=log --graph --all --pretty=format:'%C(yellow)%h%C(cyan)%d%Creset %s %C(white)- %an, %ar%Creset'
alias.ll=log --stat --abbrev-commit
alias.lg=log --color --graph --pretty=format:'%C(bold white)%h%Creset -%C(bold green)%d%Creset %s %C(bold green)(%cr)%Creset %C(bold blue)<%an>%Creset' --abbrev-commit --date=relative
alias.llg=log --color --graph --pretty=format:'%C(bold white)%H %d%Creset%n%s%n%+b%C(bold blue)%an <%ae>%Creset %C(bold green)%cr (%ci)' --abbrev-commit
alias.d=diff
alias.master=checkout master
alias.spull=svn rebase