Git版本控制总结回顾

工作这一年当中,入门学习了Git版本控制。(对于一个软件的开发,不会只有你一个人,所以你需要版本控制的工具)

看了几个教程:

1.2016年底看的入门教程:廖雪峰的Git教程

2.2017年回顾的连猴子都懂的Git入门指南

3.2018年最近粉上的很可爱的莫烦python里面的Git你的版本管理顾问

4.GIt文档


大家可以根据自己的喜好去看看这些优秀的文章和视频。

虽然用了快1年的Git,但是最常用的就是git add 和git commit指令,所以每次快要忘记的时候都要重新温故一下。。

(可能自己比较笨,不过看了这3个之后,它们互相有补充,对Git有了更深入的认识)


(以下总结基于莫烦的版本控制)

------------------------------------------------------------------------------------

1.理解概念:

版本控制,就是来管理你每一次改动的文件(.txt  .py 以及跟着基于文本信息的文件 ),可以任意回到你改动的版本。


2.创建git的版本库:

就是你之后要进行创造的文件夹,在该目录下创建个Git,用来管理文件。

创建一个文件(任何方式创建都可以,windows右键新建文件)

打开终端到该文件目录下

a. Git支持多人操作。因此需要你记录一下自己的用户名和邮箱,方便大家知道这是谁改动的文件:

$ git config --global user.name "ziqi"

$ git config --global user.email "[email protected]"
b.创建git:
$ git init
# Initialized empty Git repository in /Users/xxx/Desktop/doucmentName/.git/

3.添加文件,并用Git管理它:

创建一个文本文件(任何方式创建都可以,windows右键新建)

如:

$ touch 1.py

查看状态

$ git status 

将1.py添加进版本库

$ git add 1.py

如果想一次性添加文件夹中所有未被添加的文件, 可以使用这个:

$ git add .


4. 提交改变(commit)

$ git commit -m "create 1.py"

-m  (表示message)后面接着你对这次提交的说明


整个上述过程可以被这张 git 官网上的流程图直观地表现:

第一个版本库 Repository



其他比较不常用但也很重要但操作:


5.修改已经commit的版本(不常用)

有时候我们总会忘了什么, 比如已经提交了 commit 却发现在这个 commit 中忘了附上另一个文件,

新建2.py,模拟这种情况。

$ git add 2.py
$ git commit --amend --no-edit   # "--no-edit": 不编辑, 直接合并到上一个 commit
$ git log --oneline    # "--oneline": 每个 commit 内容显示在一行


6.reset

a.回到add之前 (不常用)

有时我们添加 add 了修改, 但是又后悔, 并想补充一些内容再 add. 这时, 我们有一种方式可以回到 add 之前. 比如在 1.py 文件中添加这一行:

d=3
然后  add  去  staged  再返回到  add  之前:
$ git add 1.py
$ git status -s # "-s": status 的缩写模式
# 输出
M  1.py     # staged
-----------------------
$ git reset 1.py
# 输出
Unstaged changes after reset:
M	1.py
-----------------------
$ git status -s
# 输出
 M 1.py     # unstaged


b.回到commit之前

在穿梭到过去的 commit 之前, 我们必须了解 git 是如何一步一步累加更改的. 我们截取网上的一些图片 http://bramus.github.io/ws2-sws-course-materials/xx.git.html

回到从前 (reset)

回到从前 (reset)

回到从前 (reset)

回到从前 (reset)

每个 commit 都有自己的 id 数字号, HEAD 是一个指针, 指引当前的状态是在哪个 commit. 最近的一次 commit 在最右边, 我们如果要回到过去, 就是让 HEAD 回到过去并 reset 此时的 HEAD 到过去的位置.

# 看看所有的log
$ git log --oneline
# 输出
904e1ba change 2
c6762a1 change 1
13be9a7 create 1.py
-----------------------
# 回到 c10ea64 change 1
# 方式1: "HEAD^"
$ git reset --hard HEAD^  

# 方式2: "commit id"
$ git reset --hard c6762a1
-----------------------
# 看看现在的 log
$ git log --oneline
# 输出
c6762a1 change 1
13be9a7 create 1.py

git reflog, 查看最近做的所有 HEAD  的改动, 并选择想要挽救的  commit id :
$ git reflog
# 输出
c6762a1 HEAD@{0}: reset: moving to c6762a1
904e1ba HEAD@{1}: commit (amend): change 2
0107760 HEAD@{2}: commit: change 2
c6762a1 HEAD@{3}: commit: change 1
13be9a7 HEAD@{4}: commit (initial): create 1.py


7.  checkout 

a.checkout 让单个文件回到过去

将 1.py 的指针 HEAD 放在这个时刻 c6762a1:

$ git log --oneline
# 输出
904e1ba change 2
c6762a1 change 1
13be9a7 create 1.py
---------------------
$ git checkout c6762a1 -- 1.py

b. 在修改文件之后,add操作之前,觉得最近刚刚睡醒写了一堆bug,删起来太麻烦,直接checkout文件以下就好啦:

如,刚在1.py加了一堆bug,想删掉:

git checkout -- 1.py

c. 切换分支:

从master切换到dev

git checkout dev



8. 创建分支:

我们之前的文件当中, 仅仅只有一条 master 分支, 我们可以通过 --graph 来观看分支:

$ git log --oneline --graph
# 输出
* 47f167e back to change 1 and add comment for 1.py
* 904e1ba change 2
* c6762a1 change 1
* 13be9a7 create 1.py


$ git branch dev    # 建立 dev 分支
$ git branch        # 查看当前分支

# 输出
  dev       
* master    # * 代表了当前的 HEAD 所在的分支

当我们想把 HEAD 切换去 dev 分支用到 checkout:

$ git checkout dev

# 输出
Switched to branch 'dev'
--------------------------
$ git branch

# 输出
* dev       # 这时 HEAD 已经被切换至 dev 分支
  master

方法2:

直接创建和切换到新建的分支:

$ git checkout -b  dev

# 输出
Switched to a new branch 'dev'
--------------------------
$ git branch

# 输出
* dev       # 这时 HEAD 已经被切换至 dev 分支
  master


删除分支:(强行删除用-D)

git branch -d dev

9. 将dev分支推送到master

因为当前的指针 HEAD 在 dev 分支上, 所以现在对文件夹中的文件进行修改将不会影响到 master 分支.

我们要将 dev 中的修改推送到 master 中, 大家就能使用到正式版中的新功能了.

$ git checkout master   # 切换至 master 才能把其他分支合并过来

$ git merge dev         # 将 dev merge 到 master 中
$ git log --oneline --graph

# 输出
* f9584f8 change 3 in dev
* 47f167e back to change 1 and add comment for 1.py
* 904e1ba change 2
* c6762a1 change 1
* 13be9a7 create 1.py

要注意的是, 如果直接 git merge dev, git 会采用默认的 Fast forward 格式进行 merge, 这样 merge 的这次操作不会有 commit 信息. log 中也不会有分支的图案. 我们可以采取 --no-ff 这种方式保留 merge 的 commit 信息.

$ git merge --no-ff -m "keep merge info" dev         # 保留 merge 信息
$ git log --oneline --graph

# 输出
*   c60668f keep merge info
|\  
| * f9584f8 change 3 in dev         # 这里就能看出, 我们建立过一个分支
|/  
* 47f167e back to change 1 and add comment for 1.py
* 904e1ba change 2
* c6762a1 change 1
* 13be9a7 create 1.py


10. merge分支冲突

<<<<<<<======= 和 >>>>>>> 隔开2个branch的冲突。merge冲突时要手动处理

在master使用merge的时候,有冲突时,Git 作了合并,但没有提交,它会停下来等你解决冲突。需要手动修改文本,再add,commit操作。

如下图:

merge 分支冲突



11.rebase 分支冲突

同样是合并 rebase 的做法和 merge 不一样.

什么是rebase:

    

假设共享的 branch 是 branch B, 而我在 branch A 上工作, 有一天我发现branch B已经有一些小更新, 我也想试试我的程序和这些小更新兼不兼容, 我也想合并, 这时就可以用 rebase 来补充我的分支branch B的内容. 补充完以后, 和后面那张图的 merge 不同, 我还是继续在 C3 上工作, 不过此时的 C3 的本质却不一样了, 因为吸收了那些小更新. 所以我们用 C3' 来代替.

rebase 分支冲突

rebase 分支冲突

rebase 分支冲突

rebase 分支冲突

可以看出 rebase 改变了 C3 的属性, C3 已经不是从 C1 衍生而来的了. 这一点和 merge 不一样. merge 在合并的时候创建了一个新的 C5 commit. 这一点不同, 使得在共享分支中使用 rebase 变得危险. 如果是共享分支的历史被改写. 别人之前共享内容的 commit 就被你的 rebase 修改掉了.

rebase 分支冲突

所以需要强调的是 !!! 只能在你自己的分支中使用 rebase, 和别人共享的部分是不能用 !!!. 如果你不小心弄错了. 没事, 我们还能用在 reset 这一节 提到的 reflog 恢复原来的样子. 为了验证在共享分支上使用 rebase 的危险性, 我们在下面的例子中也验证一下.


12. 临时修改(stash)

想想有天在开开心心地改进代码, 突然接到老板的一个电话说要改之前的一个程序. 怎么办? 虽然还需要很久时间才能改进完自己的代码, 可我有强迫症, 又不想把要改的程序和自己改进代码的部分一起 commit 了.

这时 stash 就是我的救星了. 用 stash 能先将我的那改进的部分放在一边分隔开来. 再另外单独处理老板的任务.


暂存修改

git stash

恢复暂存

git stash pop


猜你喜欢

转载自blog.csdn.net/qq_20417499/article/details/80280472
今日推荐