Git 学习笔记

131 阅读14分钟

本文已参与「新人创作礼」活动,一起开启掘金创作之路。

1 创建版本库

  • 版本库又名仓库,英文名称是repository

  • 如何创建一个版本库,

    mkdir GitRepository
    cd GitRepository
    git init
    

    这样一个新的版本库就建立好了

2 添加文件到版本当前版本库

  • 下面是操作命令

    vim readme,txt # 内容随意
    git add readme.txt  # 添加文件到仓库
    git commit -m '本次提交的说明,具有意义的说明'  # 将文件提交到仓库
    
    git commit -m 'wrote a readme file again'
    [master f4294a4] wrote a readme file again
    1 file changed, 1 insertion(+), 1 deletion(-)
    
  • 上面的提示告诉我们,1个文件被改动(添加了1个新的文件),插入了1行内容() 1行缺失

    疑问:为啥有了git add, 还需要git commit -m ' ' 因为git commit一次可以提交很多文件,所以你可以多次add不同的文件,比如:

    git add file1.txt
    git add file2.txt file3.txt
    git commit -m 'add 3 files'
    

3 修改文件

  • 下面是操作命令

    vim readme.txt # 随意修改
    git status # 查看当前版本库的状态
    

    显示结果为

    位于分支 master
    尚未暂存以备提交的变更:
    	(使用 "git add <文件>..." 更新要提交的内容)
    	(使用 "git checkout -- <文件>..." 丢弃工作区的改动)
    		修改:     readme.txt
    修改尚未加入提交(使用 "git add" 和/或 "git commit -a"
  • 上面的提示告诉我们 readme.txt 文件已经被我们修改了,但是还没有准备提交

    git diff readme.txt  # 查看readme.txt文件哪里被修改
    diff --git a/readme.txt b/readme.txt
    	index f362e74..be74d7a 100644
    	--- a/readme.txt
    	+++ b/readme.txt
    	@@ -1,2 +1,2 @@
    	-Git is a version control system
    	+Git is a distributted version control system
    	Git is a free software
    
  • 上面的提示告诉我们,我们增加了一个"distributted"单词 知道了是什么修改之后我们可以提交修改后的文档

    git add readme.txt
    git status # 查看状态
    位于分支 master
    	要提交的变更:
     	(使用 "git reset HEAD <文件>..." 以取消暂存)
    		修改:     readme.txt
    # 上面的提示告诉我们,将要被提交的修改包括readme.txt
    git commit -m 'add distributted'
    git status # 查看状态
    

4 版本回退

  • 一个文件需要不停的修改,commit 被理解为是保存一个快照,依靠快照可以进行文件版本的回退和前进

  • readme.txt 文件有两个 commit git log 查看最近到最远的提交日志

    commit e8574e2fb9c41064114a3c4cd95e59f89e5d6aa8 (HEAD -> master)
    Author: suhang <1552899301@qq.com>
    Date:   Sat Apr 20 17:23:04 2019 +0800
    
    add distributted
    
    commit f4294a40f471bd8643020e8b9d244af02182b241
    Author: suhang <1552899301@qq.com>
    Date:   Sat Apr 20 16:45:30 2019 +0800
    
    wrote a readme file again
    
    commit 99222c5143e88259af1ee1acf3f482c1a50b2d68
    Author: suhang <1552899301@qq.com>
    Date:   Sat Apr 20 16:07:31 2019 +0800
    
    wrote a readme file
    
  • 日志按照修改时间从上往下为近到远 用 HEAD 表示当前版本 上一个版本就是 HEAD^, 上上一个版本就是 HEAD^^, 向上 100 个版本就是 HEAD^~100

    git reset --hard HEAD^  # 返回上一个版本
    
  • 既然返回上一个版本,怎样返回去呢,使用版本号可以回去 (使用 git reflog) 查看使用命令,此时查看每一个版本的版本号:

    git reset --hard e8574  # e8574为commit 的前几位- 
    

5 工作区 (Working Directory)

  • gitspeace 就是一个工作区

6 版本库 (Repository)

  • 工作区有一个隐藏的目录 .git 这个不算工作区,算是 Git 的版本库
  • Git 的版本库中存放着许多的文件,最为重要的是 stage 或者叫 index 的暂存区,还有Git为我们创建的一个分支 master。
  • 可以简单的理解为:使用git add可以把需要提交的文件修改通通添加到 stage (index) 暂存区, 然后再使用 git commit -m '提示' 将暂存区的文件一次性提交到 master 分支

7 管理修改

  • Git 具有跟踪修改的特点: 第一次修改 git add 第二次修改 git commit
  • 上面的流程第二次修改是不会成功的,因为每一次修改之后,不使用 git add 到暂存区,就不会加入到 commit 中
  • 上面的流程可以更改为: 第一次修改 git add 第二次修改 git add 最后 git commit

8 撤销修改

(1) 更改文件之后,但是没有使用 git add 将修改文件添加到暂存区,可以使用一下命令

git checkout -- filename # 丢弃工作区的改动

(2) 如果将文件修改之后,而且使用了 git add 将文件添加到暂存区,但是没有使用 git commit 添加到分支,此时使用 git reset HEAD 取消暂存此时修改之后而且被添加到暂存区的文件,将会回退到到工作区,注意的是被修改的状态仍未被回退,使用 git checkout -- filename 放弃工作区的修改

9 删除文件

  • 当你删除了工作区的文件之后,使用 git status 查看当前版本库的状态
  • 使用 git checkout -- filename 撤销删除 (将版本库中的文件替换到工作区) 或者使用 git rm 删除版本库的文件
  • 使用 git commit 'remove file' 添加快照

10 配置 github 远程仓库

  • 下面是操作命令

    ssh-keygen -t rsa -C "1552899301@qq.com"
    # 回车 默认秘钥生成位置为.ssh/ 输入秘钥密码 (可选)
    # 此密码在 git remote add origin git@github.com:username/yourRepository.git (关联远程仓库) 时候使用
    git push -u origin master # 推送内容到远程库上
    # 因为远程库是空的,我们第一次推送 master 分支时候,加上 -u 参数,不但会把本地的 master 分支内容推送到远程的新仓库,还把本地的 master 和本地的 master 关联起来
    

11 从远程仓库克隆

  • 首先,在 github 官网上创建仓库,然后克隆到本地 记得勾选 Initialize this repository a README
  • 使用 git clone git@github.com:yourname/yourRepository.git

12 分支管理

​ 分支的作用是,当你准备开发一个新的功能的时候,但是需要两周才能完成,第一周你写了50%的代码,如果不能立刻提交,由于代码还没完成,不完整的代码库会导致别人无法工作,如果等代码全部再一次提交,又存在丢失进度的风险,现在有了分支,就不用怕了。你创建了一个属于你自己的分支,别人看不到,还继续在原来的的分支上正常工作,而你在你的分支上干活,想提交提交,直到开发完毕后,再一次性合并到原来的分支上,这样,既安全,又不会影响别人工作。

13 创建分支

  • 在版本会退中,你已经知道,每一次提交,Git都把他们串成一条时间线,这条时间线就是一个分支,Git中的master分支称为主分支,HEAD严格来说并不是指向提交,而是指向master,master才指向提交,所以HEAD指向的是当前分支

  • 一开始的时候,master分支是一条线,Git用master指向最新的提交,再用HEAD指向master,就能确定当前分支,以及当前分支的提交点:

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

  • 每一次提交,master分支都会向前移动一步,这样随着不断的提交,master分支的线会越来越长当我们创建新的分支的时候,例如dev,Git新建了一个指针dev,指向master相同的提交,再把HEAD指向dev,就表示在当前分支在dev上现在会与工作区的修改和提交就是针对dev分支了,比如,提交一次之后,dev向前移动一步,而master指针不变,假如我们在dev上的工作完成了,就可以把dev合并到master上

  • 下面是一个简单的操作:

    git checkout -b dev # 创建一个dev分支,然后切换到dev分支
    git branch # 查看当前分支,会在当前分支前面标记一个*
    # 此时修改readme.txt 增加随意的一句话
    git checkout master # dev的分支的工作完成之后,我们就可以切换回master分支:
    # 此时查看readme.txt 发现文件并没有改变,原因在于改变文件的操作是在dev分支上完成的,跟master没有任何关系,这时候我们需要完成合并分支的操作
    git merge dev  # 将当前分支合并 (master) 到 dev 上
    git branch -b dev # 删除dev分支
    

14 解决冲突

在合并分支的时候,会出现冲突问题

下面是一个简单的例子:
创建分支fea 并且换为当前分支
    	git checkout -b fea
修改readme.txt 增加一句话 001
提交分支:
    	git add readme.txt
    	git commit -m "001"
切换到主分支
    	git checkout master
修改readme.txt 增加一句话 002
提交分支:
    	git add readme.txt
    	git commit -m "002"
合并分支 
    	git merge fea
提示报错,因为,两个分支分别对文件进行了不同的修改,自然无法合并。此时需要解决冲突,就是修改刚才合并失败的文件
    	vim readme.txt
分之1:001
分支2:002
随便删除一个就好
提交分支:
    	git add readme.txt
    	git commit -m "fixed"

15 分支管理策略

  1. 通常合并分支,如果可能,git会采用fast forward模式,但是这种模式下,删除分支之后,会丢失一些分支信息,如果轻质禁用fast forward模式,git就会在merge时,生成一个新的commit,我们从分支历史上就可以看到分支信息
下面我们使用--on--ff的方式git merge
首先,创建并且切换到dev分支
    	git checkout -b dev
修改readme.txt文件
    	git add readme.txt
    	git commit "add merge"
切换到master分支
    	git checkout master
准备合并dev分支,使用--no--ff(禁用fast forward)
    	git merge--no-ff -m "merge with no-ff" dev  本次合并要创建一个新的commit,所以加上-m参数,把commit描述写进去
使用git log看看分支历史
    	git log -- grep -pretty=oneline --abbrev-commit
  1. 分支管理策略
  • 首先,master分支应该是最稳定的,也就是仅用来发布新版本的,平时不能用来干活;
  • 平时工作均在dev分支上,也就是说,dev是不稳定的,比如说要发布1.0版本的时候。再把dev分支合并到master上,在master分支上发布1.0版本,你和你的小伙伴都在dev上干活,每个人都有子的分支,时不时的往master上合并

16 Bug分支

  • 在软件开发中,bug就像家常便饭一样,有了bug就需要修复,在Git中,由于分支是如此的强大,所以,每一个bug都可以通过一个新的临时分支修复,合并分支,然后将临时分支删除

  • 当你接受到一个修复1号代码,创建一个分支01来修复它,但是,等等当前正在dev上进行的工作还没有提交:

    • Git提供了一个stash功能,可以把当前工作现场"储藏"起来,等以后在恢复使用
  • 首先确定bug是位于哪一个分支上的,加入在主分支上,就从主分支master创建临时分支

    git checkout -b 01
    现在修复bug,编辑readme.txt
    修复完成后,提交
        git add readme.txt
        git commit -m "bug fixed" 
    切换分支
        git checkout master
    合并分支
        git merge --no-ff -m "merge bug fix 01" 01
    切换回刚才工作的分支
        git checkout dev
        git status 查看状态
    显示工作区是干净的
        git stash list 查储藏工作区列表
    第一种是:git stash apply恢复 但是stash没有删除,需要使用
        git stash drop 删除 
    第二种是:git stash pop 恢复的同时把stash也删除了
    可以多次stash 恢复的时候,先用git stash list查看,最后恢复指定的stash git stash apply stash@{0}
    

17 新功能分支

  • 当你要开发一个新功能的时候,需要创建一个分支,等到新功能开发好,再合并分支,然后删除新的分支
  • 使用git branch -D 分支名称 -D 强制删除

18 多人协作

  • 当你从远程仓库克隆时候,实际上把Git自动把本地的master分支和远程的master分支对应起来了,并且,远程仓库的默认名称是origin 使用git remote 或者使用 git remote -v显示更详细的信息;

  • 例如:

    git remote -v 
    origingit @github.com:suhang12332/gitspeace.git(fetch)
    origin git@github.com:suhang12332/gitspeace.git(push)
    

上面显示了可以抓取和推送的origin的地址,如果没有推送权限,就看不到push的地址

  • 推送分支:就是把该分支上的所有本地提交推送到远程库。推送时,要指定本地分支,这样,Git就会把该分支推送到远程库对应的远程分支上;

    git push origin master
    如果需要推送其他分支,比如dev
    git push origin dev
    
  • 抓取分支

    • 多人协作时,大家都会往master和dev分支上推送各自修改。现在,模拟一个你的小伙伴,可以在另一台电脑(注意要把SSH添加到github)或者同一台电脑的另一个目录下克隆

      git clone git@github.com:suhang12332/gitspeace.git
      
    • 当你的小伙伴从远程clone时,默认情况下,你的小伙伴只能看到本地的master分支 使用git branch 现在,你的小伙伴要在dev上开发分支,就必须创建origin到dev分支到本地dev

      git checkout -b dev origin/dev
      创建完成后,就可以在dev分支上继续修改,然后时不时的将dev分支推送到远程分支上
             git add ***.txt
             git commit -m "add ***"
             此时你也向origin/dev分支提交,并试图推送,
             git add ***.txt
             git commit -m "add new ***"
             git push origin dev
      
    • 推送失败,因为你的小伙伴的最新提交和你试图提交有冲突,解决办法很简单,git已经提示我们,先用git pull把最新的origin/dev抓下来,然后合并,解决冲突,再推送

    • git pull 这样使用是失败的因为你没有指定本地dev与远程origindev分支的链接,根据提示,设置dev和origin/dev的链接

      git branch --set-upstream-to=origin/dev/dev
      git pull
      
    • 可以总结:多人协作的模式如下:

      • 1.首先,可以试图git push origin 推送自己的修改

      • 2.如果推送失败,因为远程分支比你本地更新,首先使用git pull合并

      • 3.合并之前要指定本地的分支与远程的分支链接 git branch --set-upstream-to=origin/dev/dev

      • 4.合并没有冲突,即本地提交,有冲突,解决冲突

      • 5.没有冲突使用

         git push origin <branch name>
        

19 整理分支合并

使用 git rebase 整理 使用、查看

20 标签管理

  • 创建标签:首先切换到需要打标签的分支上

    git checkout master 
    
  • 然后

    git tag v1.0
    # 使用 -a 指定标签名字 使用 -m 指定说明文字
    git tag -a v0.9 -m"version0.9" commit号码使用git tag查看所有标签
    # 还可以使用 git tag v1.0 commit 号码,标签的顺序是按照字母的顺序排列的
    # 使用 show tagname 查看标签属性	
    
  • 操作标签: 打错名字可以删除:

    git tag -d tagname
    
  • 推送标签到远程

    git push origin tagname
    
  • 说着一次性推送完所有的标签

    git push origin -tags
    
  • 删除远程标签;先删除本地,再删除远程

    git push origin :refs/tags/v0.9
    

Tips

1) 限制 clone 深度,加快下载速度

仅是 clone 此仓库学习(不是参与翻译工作)的话,请使用如下 Git 命令

git clone --depth 1 https://github.com/labuladong/fucking-algorithm.git

这样会限制 clone 的深度,不会下载 Git 协作的历史记录,可以极大加快下载速度。

2) 解决:'touch' 不是内部或外部命令,也不是可运行的程序或批处理文件

在 Windows 的 cmd 中我们可以使用 echo test>

image-20200809183113702

3) 初始化本地项目到 Git 仓库

# 初始化本地仓库
git init
# 将本地内容添加至git索引中
git add .
# 将索引添加至本地仓库中
git commit -m "first commit"
# 添加远程仓库路径
git remote add origin https://github.com/coderliguoqing/vans.git
# 将本地内容push至远程仓库中
git push -u origin master

4) Git 关闭换行符提示

git config --global core.autocrlf false