vlambda博客
学习文章列表

[利器]git常用操作--本地

工欲善其事,必先利其器



git是跨平台的,在linux、windows、mac上都能使用的优秀的版本管理工具。




git干啥的?


为什么要用git?话不多说,看图:

[利器]git常用操作--本地

你是否也有这样的遭遇,文件有很多个版本,管理这些版本使你快要崩溃。


git就是解决这个问题的,它把所有的修改记录下来,你可以自由的修改,不怕改错,因为你可以随时返回到某个历史版本。





git如何管理文件


那git是如何管理文件的呢?


git是以目录(就是文件夹)为单位管理的,在你的目录git_test(假设是空的,不是空的也可以)中执行:

ymj@ymj-pc:~/git_test$ git init已初始化空的 Git 仓库于 /home/ymj/git_test/.git/

此时目录git_test就已经使用git管理了,从上面的输出可以看出:

git在当前目录创建了一个.git的目录(linux中以一个小圆点开头的文件是隐藏文件)保存所有的修改历史等。对于.git的内容先不去关心,就知道是git为了管理版本必须创建该目录。


这样的目录拷贝到别的地方也能正常工作,是一个完整的git项目。

[利器]git常用操作--本地


在工作区就像没有git一样,创建,修改你的文件就好。git会把历史记录保存在.git中,叫做:版本库。


git并不是时刻都保存你的修改,也不是保存你所有的修改。你要告诉git什么时候保存哪些修改。


所以,git在实现的时候是这样的:

在工作区和版本库之间有一个暂存区(stage),你可以把修改的内容添加(add)到暂存区,然后可以把暂存区的内容提交(commit)到版本库。可以通过diff命令查看各个区域的差异。了解这个过程是非常重要的。






举个栗子


举例之前先配置一下git,否则在后续操作过程中git会提示需要配置email和name。~/git_test$ git config --global user.email "[email protected]"~/git_test$ git config --global user.name "YMJ"


在git_test目录创建一个空文件,并提交到版本库。

ymj@ymj-pc:~/git_test$ touch readme.txt ymj@ymj-pc:~/git_test$ git add readme.txt ymj@ymj-pc:~/git_test$ git commit -m "init commit"[master (根提交) 43b1405] init commit 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 readme.txt

上面的操作我们

  1. 先通过“touch readme.txt”创建了一个空文件。

  2. 通过“git add readme.txt”添加修改到暂存区。

  3. 通过“git commit -m“init commit””提交到版本库,-m 后面的是提交说明。


查看一下提交记录

ymj@ymj-pc:~/git_test$ git logcommit 43b1405a462fb0b460594534006f12d0a7c0a2d6 (HEAD -> master)Author: YMJ <576648661@qq.com>Date: Sat Jan 4 21:30:43 2020 +0800
    init commit

使用“git log” 可以看到谁在什么时候提交了“init commit”的记录。

最上面commit后面的数字 43b1405a462fb0b460594534006f12d0a7c0a2d6是本次提交的编号(CID),每次提交的编号是不同的。


重新创建一个文件math.txt, 并查看工作区状态

ymj@ymj-pc:~/git_test$ touch math.txtymj@ymj-pc:~/git_test$ git status 位于分支 master未跟踪的文件: (使用 "git add <文件>..." 以包含要提交的内容)
math.txt
提交为空,但是存在尚未跟踪的文件(使用 "git add" 建立跟踪)

git status 看到有“未跟踪的文件”建议使用git add建立跟踪。(顺便提一句,断开一个文件的跟踪用git rm --cached)

git对跟踪的文件进行记录,建立跟踪的方法就是git add。我们实验一下:

ymj@ymj-pc:~/git_test$ git add math.txt ymj@ymj-pc:~/git_test$ git status 位于分支 master要提交的变更: (使用 "git reset HEAD <文件>..." 以取消暂存)
  新文件:   math.txt

看到我们已经跟踪了math.txt,也就是添加到了暂存区。

同时git也提示
  (使用 "git reset HEAD <文件>..." 以取消暂存)
通过add能把修改添加到暂存区,通过git reset可以从暂存区撤销修改。


在math.txt中写“1 + 1 = 3”,然后通过git diff比较工作区,暂存区,和版本库的关系

// 增加一行ymj@ymj-pc:~/git_test$ cat math.txt 1 + 1 = 3
// 查看状态,// "要提交的变更" 是暂存区未提交到版本库的内容:有新文件math.txt// "尚未暂存以备提交的变更" 是工作区未添加到暂存区的改动。// 同时都提示了怎样撤销改动ymj@ymj-pc:~/git_test$ git status 位于分支 master要提交的变更: (使用 "git reset HEAD <文件>..." 以取消暂存)
新文件:math.txt
尚未暂存以备提交的变更: (使用 "git add <文件>..." 更新要提交的内容) (使用 "git checkout -- <文件>..." 丢弃工作区的改动)
  修改:     math.txt    // 查看工作区和暂存区的差异//显示"+1 + 1 = 3","+"号代表增加一行,如果删除一行就是"-"ymj@ymj-pc:~/git_test$ git diffdiff --git a/math.txt b/math.txtindex e69de29..cdd4b8a 100644--- a/math.txt+++ b/math.txt@@ -0,0 +1 @@+1 + 1 = 3

// 查看暂存区和版本库的差异// 因为暂存区只用空文件,我们还没把新行添加到暂存区,// 所以暂存区和版本库只差一个空文件ymj@ymj-pc:~/git_test$ git diff --cacheddiff --git a/math.txt b/math.txtnew file mode 100644index 0000000..e69de29

// 查看工作区和版本库之间的差异// 有新文件,和增加一行ymj@ymj-pc:~/git_test$ git diff HEADdiff --git a/math.txt b/math.txtnew file mode 100644index 0000000..cdd4b8a--- /dev/null+++ b/math.txt@@ -0,0 +1 @@+1 + 1 = 3


要将修改的math.txt提交还是要git add之后,git commit。

时刻清楚,git add是把修改的部分添加到暂存区,只有添加到暂存区的内容才可以提交到版本库。


总结

  • CID = commit ID, 不填则为HEAD(最新CID)。(CID比较长,为了简单,可使用前面一部分)

  • [file] 表示可选的文件名,不填则为CID对应的所有改动的文件。

  • <file>表示必填的文件名。


解释一下上图中的git命令:

add

将改动添加到暂存区。


commit

将暂存区,提交到版本库。


diff

对比工作区和暂存区的差异。


diff --cached

对比暂存区和版本库的差异。


diff HEAD

对比工作区和版本库的差异。


reset [file]

把add到暂存区的内容,还原到工作区。也就是取消add。


reset --soft CID [file]

reset CID [file]  (完整为reset --mixed CID [file])

reset --hard CID [file]

3条命令都是将版本库回退到CID,根据参数不同表现不同:

--hard  

库,stage,工作区完全同步到CID,其他内容丢失。

--soft

库到CID,差异到stage,工作区不变,内容不丢失。

--mixed(default)

库到CID,清空stage,差异到工作区,内容不丢失。


checkout CID -- <file>

库不变,将工作区指定的文件恢复到CID,stage清空,file修改的内容会丢失。

reset和checkout对于工作区有些地方比较像,区别在于reset改变版本库,checkout不会改变版本库。


rm

要删除一个用git跟踪的文件,不能直接删除,要使用git rm <file>。

只断开跟踪,不删除文件使用git rm --cached <file>。




查看版本库


因为人们有各种各样的理由查看版本库:提交了几次?那次提交修改了什么?是谁什么时候提交了什么文件?这一行代码是谁写的?从CID1到CID2都改了什么?一个文件的修改历史?一个目录的修改历史?......所以git也提供了各种各样的查看方法。


下面列举查看版本库常用的方法,请根据需求自行选择:

  1. git log                       // 查看提交总体情况

  2. git whatchanged // 查看提交修改了哪些文件

  3. git blame                // 查看文件每一行的修改情况

  4. git show                  // 查看某次体提交修改了哪些内容

  5. git diff                      // 比较灵活的查看

这些命令都可以这样使用:

git CMD [CID] [file/dir] [OPT]
[CID]  指定哪次提交。

[file/dir] 指定文件和目录查看该文件或目录的信息。

[OPT] 常用的有“--oneline,--name-only,--stat,--name-status”。


利用刚才的git_test项目分别看看他们的用法:

git log

ymj@ymj-pc:~/git_test$ git logcommit cbdc648f33bfa748e619aaa87fece9650da6a5f9 (HEAD -> master)Author: YMJ <[email protected]>Date: Sun Jan 5 14:55:47 2020 +0800
fix bug
commit e595e94375551ad88e9fe1ee081a970f80da3083Author: YMJ <[email protected]>Date: Sun Jan 5 11:00:40 2020 +0800
add math.txt
commit 43b1405a462fb0b460594534006f12d0a7c0a2d6Author: YMJ <[email protected]>Date: Sat Jan 4 21:30:43 2020 +0800
    init commit

可以看出有3次提交,谁什么时候提交、commit ID都可以看出来,按时间顺序依次为:

init commit

add math.txt

fix bug


如果你觉得上面的信息太多了,可以试试:

git log --oneline

ymj@ymj-pc:~/git_test$ git log --onelinecbdc648 (HEAD -> master) fix buge595e94 add math.txt43b1405 init commit

--oneline 连CID 都显示的短了。为了显示的更清晰,后面都加上--oneline,当然你实际工作中可以不加。


git whatchanged

ymj@ymj-pc:~/git_test$ git whatchanged --onelinecbdc648 (HEAD -> master) fix bug:100644 100644 fd273b9 2ec5ffb M math.txte595e94 add math.txt:000000 100644 0000000 fd273b9 A math.txt43b1405 init commit:000000 100644 0000000 e69de29 A        readme.txt

文件名前面的字母A和M分别代表增加文件(Add)和修改文件(Modify)

可看出3次提交,分别为:

增加文件 readme.txt

增加文件 math.txt

修改文件 math.txt


git blame

ymj@ymj-pc:~/git_test$ git blame math.txtcbdc648f (YMJ 2020-01-05 14:55:47 +0800 1) 1 + 1 2

math.txt 只有1行,是YMJ提交的。


git show

ymj@ymj-pc:~/git_test$ git show --onelinecbdc648 (HEAD -> master) fix bugdiff --git a/math.txt b/math.txtindex fd273b9..2ec5ffb 100644--- a/math.txt+++ b/math.txt@@ -1 +1 @@-1 + 1 = 3+1 + 1 = 2

可以看出,最后一次提交fix bug,

删除了一行:1 + 1 = 3

增加了一行:1 + 1 = 2

也就是把1+1=3修改为1+1=2。


git diff

ymj@ymj-pc:~/git_test$ git log --onelinecbdc648 (HEAD -> master) fix buge595e94 add math.txt43b1405 init commitymj@ymj-pc:~/git_test$ git diff 43b1405 e595e94diff --git a/math.txt b/math.txtnew file mode 100644index 0000000..fd273b9--- /dev/null+++ b/math.txt@@ -0,0 +1 @@+1 + 1 = 3ymj@ymj-pc:~/git_test$ git diff 43b1405 cbdc648diff --git a/math.txt b/math.txtnew file mode 100644index 0000000..2ec5ffb--- /dev/null+++ b/math.txt@@ -0,0 +1 @@+1 + 1 = 2

git diff 比较了前两次(通过指定CID)的差异显示,2次提交增加了一行:

1 + 1 = 3

又通过git diff 查看了第1次和第3次的提交,2次提交增加了一行:

1 + 1 = 2



好了,常用的git本地操作就是这些,关于指定[CID][file/dir][OPT]的情况自己尝试,不明确指出CID和目录的默认值就是最后一次提交和工作区。


----------我是比特,一个想把问题搞清楚的青年才俊----------