测试人学习Git

作为一枚测试,一直贪方便使用SourceTree工具进行Git操作,以致无法深刻理解Git的精髓,上周重新学习了廖雪峰老师的Git教程,瞬间豁然开朗。

Git安装

从官网下载Git安装包,安装完成后,打开Git Bash设置本机的用户名和邮箱。

git config --global user.name "用户名"
git config --global user.email "邮箱地址"

创建版本库及添加文件

使用git init命令可以把本地的目录变为可管理的git仓库。

git_init.png

执行完命令后,可发现目录下多了一个.git的目录。该目录是隐藏的,可使用以下命令查看。

ls -ah
git_init1.png

使用以下命令添加文件到版本库,第一步添加仓库,第二步提交仓库。

git add learn.txt
git commit -m "create learn.txt"

git_add_commit.png

再次修改本地的learn.txt文件,使用git status查看仓库状态,可以看到提示文件有改动。

$ 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:   learngit.txt

no changes added to commit (use "git add" and/or "git commit -a")

使用git diff命令对比文件改动的内容,可以看到文件后面加了一行“add by tomandy ---update1” 。

$ git diff learngit.txt
WARNING: terminal is not fully functional
diff --git a/learngit.txt b/learngit.txt
index 97f3542..12b8c54 100644
--- a/learngit.txt
+++ b/learngit.txt
@@ -1,2 +1,3 @@
 i am tomandy.
 who are you?tomandy
+add by tomandy ---update1
\ No newline at end of file

git diff #是工作区(work dict)和暂存区(stage)的比较。
git diff --cached #是暂存区(stage)和分支(master)的比较
git diff HEAD -- learngit.txt命令可以查看工作区和版本库里面最新版本的区别。

版本回退

git log或git log --pretty=oneline可以查看版本日志。

$ git log
WARNING: terminal is not fully functional
commit 90cfb6d8576f26f46159521e6e1a3f17662e769b
Author: linrongbiao <linrongbiao@hfbank.com.cn>
Date:   Tue Mar 13 14:32:31 2018 +0800

    add something

commit ad0d3bb95e93da1bf22be6d7f689e25a33c90562
Author: linrongbiao <linrongbiao@hfbank.com.cn>
Date:   Tue Mar 13 11:41:22 2018 +0800

    create learngit.txt

    
$ git log --pretty=oneline
WARNING: terminal is not fully functional
90cfb6d8576f26f46159521e6e1a3f17662e769b add something
ad0d3bb95e93da1bf22be6d7f689e25a33c90562 create learngit.txt 

在git中,HEAD表示当前版本,也就是上述的90cfb6d8576f26f46159521e6e1a3f17662e769b版本id,上一个版本是HEAD^, 上上个版本是HEAD^^,往上100个版本写成HEAD~100。可以使用git reset命令进行版本回退。

$ cat learngit.txt
i am tomandy.
who are you?tomandy
add by tomandy ---update1
$ git reset --hard head^
HEAD is now at ad0d3bb create learngit.txt

$ cat learngit.txt
i am tomandy.
who are you?tomandy

可以发现,learngit.txt回到了最初的版本,即去掉了“add by tomandy ---update1”这行。
git reflog命令记录每次执行的操作日志。

$ git reflog
WARNING: terminal is not fully functional
ad0d3bb HEAD@{0}: reset: moving to head^
90cfb6d HEAD@{1}: commit: add something
ad0d3bb HEAD@{2}: commit (initial): create learngit.txt

git reset命令也可以根据版本id进行版本回退。

$ git reset --hard 90cfb6d
HEAD is now at 90cfb6d add something

$ cat learngit.txt
i am tomandy.
who are you?tomandy
add by tomandy ---update1

可以发现,“add by tomandy ---update1”又回来了。

工作区和缓存区

工作区有个隐藏的.git目录,是Git的版本库。Git版本库提供了成为stage的暂存区,还有Git为我们自动创建的第一个分支master,以及指向master分支的一个HEAD指针。

工作区和暂缓区.png

第一步的git add相当于把文件添加到暂缓区。第二部的git commit实际上是把暂缓区的所有内容提交到当前分支。

撤销修改

git checkout -- learngit.txt用于把文件在工作区的修改全部撤销,有以下两种情况。

  • 一种是learngit.txt修改后还没放到暂存区,撤销修改后就回到和版本库一模一样的状态。
  • 一种是learngit.txt修改后已放到暂存区,工作区又做了修改,撤销修改后回到添加暂缓区一模一样的状态。
    总之就是让文件内容回到最近一次git commit或git add的状态。
$ cat learngit.txt
i am tomandy.
who are you?tomandy
add by tomandy ---update1
add by tomandy ---update2
add by tomandy ---update3

$ git checkout -- learngit.txt

$ cat learngit.txt
i am tomandy.
who are you?tomandy
add by tomandy ---update1
add by tomandy ---update2

通过以上命令,发现learngit.txt恢复为与版本库一致。
git reset head leargit.txt可以把暂存区的修改撤销掉,重新放回工作区,然后再使用git checkout -- learngit.txt撤销工作区的修改。git checkout其实是用版本库里的版本替换工作区的版本,无论工作区是修改还是删除,都可以“一键还原”。

$ git add learngit.txt

$ git status
On branch master
Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)

        modified:   learngit.txt


$ git reset head learngit.txt
Unstaged changes after reset:
M       learngit.txt

$
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:   learngit.txt

no changes added to commit (use "git add" and/or "git commit -a")

$ git checkout -- learngit.txt

$ cat learngit.txt
i am tomandy.
who are you?tomandy
add by tomandy ---update1
add by tomandy ---update2
add by tomandy ---update3

删除文件

git rm命令可以删除版本库的文件。比如删除了工作区的test.txt文件后,git status展示文件与版本库不一致,此时可以使用git rm删除版本库文件,然后再git commit。

$ rm test.txt

$ ls
learngit.txt

$ git status
On branch master
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:    test.txt

no changes added to commit (use "git add" and/or "git commit -a")

$ git rm test.txt
rm 'test.txt'

$ git commit -m "delete test.txt"
[master 4a2a120] delete test.txt
 1 file changed, 1 deletion(-)
 delete mode 100644 test.txt

远程仓库

本地Git仓库和远程Github仓库之间的传输是通过SSH加密的,所以需要先创建SSH key,创建成功的话,最终在用户目录C:\Users\lenovo.ssh下可以看到id_rsa和id_rsa.pub两个文件,把公钥的内容添加到Github。

$ ssh-keygen -t rsa -C "youremail@example.com"

为什么GitHub需要SSH Key呢?因为GitHub需要识别出你推送的提交确实是你推送的,而不是别人冒充的,而Git支持SSH协议,所以,GitHub只要知道了你的公钥,就可以确认只有你自己才能推送。
Github上建立远程仓库后,可以克隆本地,也可以把本地的Git版本库关联远程仓库,使用以下命令:

git remote add origin git@github.com:Tomandy1988/TestProject.git

或者克隆远程仓库到本地:

git clone git@github.com:Tomandy1988/TestProject.git

下一步就可以把本地库的内容全部推送到远程仓库:

$ git push -u origin master
The authenticity of host 'github.com (192.30.253.113)' can't be established.
RSA key fingerprint is 16:27:ac:a5:76:28:2d:36:63:1b:56:4d:eb:df:a6:48.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added 'github.com,192.30.253.113' (RSA) to the list of known hosts.
Counting objects: 16, done.
Delta compression using up to 4 threads.
Compressing objects: 100% (10/10), done.
Writing objects: 100% (16/16), 1.27 KiB | 0 bytes/s, done.
Total 16 (delta 3), reused 0 (delta 0)
remote: Resolving deltas: 100% (3/3), done.
To git@github.com:Tomandy1988/TestProject.git
 * [new branch]      master -> master
Branch master set up to track remote branch master from origin.

由于远程库是空的,我们第一次推送master分支时,加上了-u参数,Git不但会把本地的master分支内容推送到远程新的master分支,还会把本地的master分支和远程的master分支关联起来,在以后的推送或者拉取时就可以简化命令。
后续本地作了提交,就可以通过以下命令把本地master分支的最新修改推送至Github远程仓库:

git push origin master

创建与合并分支

master分支是一条线,Git用master指向最新的提交,再用Head指向master,就能确定当前分支,以及当前分支提交点,每次提交,master分支都会向前移动一步。

master分支.png

当我们创建新的分支dev时,Git新建了一个指针叫dev,指向master相同的提交,再把HEAD指向dev,就表示当前分支在dev上。
dev分支.png

后续对工作区的修改和提交就是针对dev分支了,比如新提交一次后,dev指针往前移动一步,而master指针不变;
dev分支2.png

dev分支的工作完成后,就可以把dev合并到master上了,接着再删除dev分支。
devmaster分支合并.png

dev分支删除.png

以下两组命令效果是一样的,创建并切换到dev分支:

$ git checkout -b dev
等同于
$ git branch dev
$ git checkout dev

git branch命令列出所有分支,当前分支前面标注*号。

$ git branch
* dev
  master

如果在dev分支进行工作,后可以通过以下命令将dev分支合并到master分支,git merge属于快进模式合并,也就是直接把master指向dev当前提交,所以合并速度非常快。

$ git merge dev
Already up-to-date.

使用git branch -d dev删除分支。

解决冲突

分支合并往往不是一帆风顺。比如创建并切换到分支feature,然后修改learngit.txt提交(增加一行“add by tomandy ---update4”)。

$ git add learngit.txt 
$ git commit -m "AND update4"

切换到master分支,增加一行“add by tomandy ---update5”到learngit.txt,此时master分支和feature分支各自都分别有新的提交,如下图所示。

冲突.png

这种情况下,Git无法执行“快速合并”,只能试图把各自的修改合并起来,但这种合并就可能会有冲突,我们试试看:

$ git merge feature1
Auto-merging learngit.txt
CONFLICT (content): Merge conflict in learngit.txt
Automatic merge failed; fix conflicts and then commit the result.

查看发现learngit.txt文件标记了不同分支的差异:

$ cat learngit.txt
i am tomandy.
who are you?tomandy
add by tomandy ---update1
add by tomandy ---update2
add by tomandy ---update3
<<<<<<< HEAD
add by tomandy ---update5
=======
add by tomandy ---update4
>>>>>>> dev

修改learngit.txt后,再提交即可解决冲突,最终master和feature分支变成如下图所示:

冲突1.png

使用以下命令可以查看分支的合并情况 。

$ git log --graph --pretty=oneline --abbrev-commit
WARNING: terminal is not fully functional
*   34fced9 add update4 not update5
|\
| * 7383c70 add update4
* | 0db4d8c add update5
|/
*   3f682d7 conflict fixed
|\
| * cd1f79b add and to test.txt
* | 211f418 add & to test.txt
|/
* daa2f86 add test.txt
* 4a2a120 delete test.txt
* 407a04b add test.txt
* 5529036 add update3
* 73f4ef3 add update2
* 90cfb6d add something
* ad0d3bb create learngit.txt

分支管理策略

通常,合并分支时,如果可能,Git会用Fast forward模式,但这种模式下,删除分支后,会丢掉分支信息。如果要强制禁用Fast forward模式,Git就会在merge时生成一个新的commit,这样,从分支历史上就可以看出分支信息。

$ git merge --no-ff -m "merge with no-ff" dev
Merge made by the 'recursive' strategy.
 readme.txt |    1 +
 1 file changed, 1 insertion(+)

在实际开发中,我们应该按照几个基本原则进行分支管理:
首先,master分支应该是非常稳定的,也就是仅用来发布新版本,平时不能在上面干活;那在哪干活呢?干活都在dev分支上,也就是说,dev分支是不稳定的,到某个时候,比如1.0版本发布时,再把dev分支合并到master上,在master分支发布1.0版本;
你和你的小伙伴们每个人都在dev分支上干活,每个人都有自己的分支,时不时地往dev分支上合并就可以了。
所以,团队合作的分支看起来就像这样:

团队合作分支.png

多人协作

以下命令查看远程仓库信息。

$ git remote
origin

$ git remote -v
origin  git@github.com:Tomandy1988/TestProject.git (fetch)
origin  git@github.com:Tomandy1988/TestProject.git (push)

当从远程库clone时,默认情况下,只能看到本地的master分支。如果要在dev分支上开发,就必须创建远程origin的dev分支到本地,可以使用以下命令创建本地dev分支。

$ git checkout -b dev origin/dev

使用以下命令指定本地dev分支与远程origin/dev分支的链接。

$ git branch --set-upstream dev origin/dev
Branch dev set up to track remote branch dev from origin.
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 214,588评论 6 496
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,456评论 3 389
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 160,146评论 0 350
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,387评论 1 288
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,481评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,510评论 1 293
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,522评论 3 414
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,296评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,745评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,039评论 2 330
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,202评论 1 343
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,901评论 5 338
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,538评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,165评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,415评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,081评论 2 365
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,085评论 2 352

推荐阅读更多精彩内容

  • 本文为 Git教程的学习笔记,教程源自廖雪峰的博客。这是一个由浅入深,学完后能立刻上手的Git教程。另,附上另一本...
    七弦桐语阅读 6,241评论 5 47
  • 1. 安装 Github 查看是否安装git: $ git config --global user.name "...
    Albert_Sun阅读 13,649评论 9 163
  • 1.git的安装 1.1 在Windows上安装Git msysgit是Windows版的Git,从https:/...
    落魂灬阅读 12,658评论 4 54
  • 经常看到很多人在炫耀自己一年读了多少本书,然后就是介绍下这本书的主要内容,除了套路化外,我们看不到读了这本书对于作...
    奔跑的汤盆儿阅读 365评论 0 0
  • 还没开始 谈何放弃 你的人生 不只是说说而已 你就是你 唯一且美丽 平淡的阳光下 有一个看是平淡的你 谁会知晓 你...
    张桃子阅读 288评论 0 1