Git学习总结

本文是git初次理论学习的总结,后期会结合实践深入学习、多次编辑。

Git基本概念

git是一个分布式版本控制系统。git库主要由三部分组成:

  1. 工作区(working dir): 用户本地的工作目录

  2. 暂存区(stage/index): 一个临时的用于放置文件改动的缓存区域

  3. 版本库(repo): 顾名思义,即包含了所有版本及分支的仓库。该仓库里面的文件能够被Git所管理,文件的增加、删除、修改都能够被Git所跟踪

初始化一个git库时,版本库为空,无论工作区有多少文件。

当在工作区执行add操作后,才会将工作区的文件提交到暂存区。

当执行commit操作并成功后,才会将暂存区的文件才会转移到版本库的当前分支中。

图中的HEAD表示当前分支的当前版本指针。

Git本地仓库操作

  • 初始化

git init

把工作区初始化为git仓库,查看工作目录中,会发现多了一个隐藏文件夹.git。此时即可进行git的各项操作了。 

  • 将工作区的文件提交到暂存区

git add <file>

git add可以进行多次提交,也可以一次性提交所有文件到暂存区

git add . :他会监控工作区的状态树,使用它会把工作时的所有变化提交到暂存区,包括文件内容修改(modified)以及新文件(new),但不包括被删除的文件。
git add -u :他仅监控已经被add的文件(即tracked file),他会将被修改的文件提交到暂存区。add -u 不会提交新文件(untracked file)。(git add --update的缩写)
git add -A :是上面两个功能的合集(git add --all的缩写)
  •  将暂存区的文件提交到版本库

git commit -m "commit comments"

"commit"命令将位于暂存区的文件提交到版本库,以便Git进行管理和跟踪,-m 后面加提交的说明。(强烈建议给出简洁但明晰的说明告知此次commit的主要目的)。至此,工作目录的文件就会加入版本库,可以被Git进行管理和跟踪。

  • 查看git库状态

可以通过查看git状态来确保每一次的操作记录和进程,以及提示工作区和版本库的差异

git status

 针对Git库状态,主要有以下几个内容:

On branch master #必然会出现的信息,告知当前所处的分支
nothing to commit, working directory clean #表示目前工作区和版本库内容一致,且暂存区无内容没有需要提交的修改
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:   readme1.txt
#表示工作区的文件已经有所改变,等待将改变放入暂存区;后续操作:add
On branch master
Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)
modified:   readme1.txt
#表示暂存区有修改信息,等待提交到版本库;后续操作:commit
  •  查看git库日志

可以通过命令查看git库提交记录以及commit id、作者等信息,方便版本退回等。

git log  # 查看默认格式的提交记录
git log -5 # 查看最近5条提交记录
git log -p # 查看提交记录并显示代码改动内容
git log -p --author=abc # 查看abc的提交记录并显示代码改动内容
git log --since=2011-05-24 --until=2011-05-25  # 查看从2011-05-24到2011-05-25的提交
git log --name-only # 只显示文件名
git log --pretty=oneline # 只显示一行
  • 撤销修改

1)当你修改了工作区中的某个文件,但此文件还未提交到暂存区。

可以使用如下命令撤销工作区的修改:

git checkout -- <file>

2)当你修改了工作区中的某个文件,且已经把该文件提交到暂存区。

可以先使用如下命令撤销暂存区的修改:

git reset HEAD <file>

然后再使用上一步说的

git checkout -- <file>

  撤销工作区的修改。

3)当你修改了工作区中的某个文件,并已经提交到版本库。

  当你修改了工作区中的某一个文件,且已经把该文件提交到暂存区,并commit到版本库了,你想让版本库回退到上一个版本。

  首先,Git必须知道当前版本是哪个版本,在Git中,用HEAD表示当前版本,上一个版本就是HEAD^,上上一个版本就是HEAD^^,当然往上100个版本写100个^比较容易数不过来,所以写成HEAD~100。

git reset --hard HEAD^

  当然你如果通过git log查看到提交记录的id,也可以直接通过commit id退回到指定版本

git reset --hard <commit_id>

      git内部其实是通过一个HEAD指针指向当前版本,版本退回也是通过移动HEAD指针的指向来实现。

  • 分支管理

在git中,每次提交,Git都把它们串成一条时间线,这条时间线就是一个分支。截止到目前,只有一条时间线,在Git里,这个分支叫主分支,即master分支。HEAD严格来说不是指向提交,而是指向master,master才是指向提交的,所以,HEAD指向的就是当前分支。

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

分支可以看做是一个指向本地仓库的不同地方的指针,所以几乎没有空间和时间的消耗,推荐多使用分支。在线上开发时master节点中一般是稳定可上线版本,一般另外创建dev分支开发新功能或debug分支来调试bug,当新功能开发调试完后,可以把修改合并到master分支上。

1)创建分支

git branch <branch_name>

2)切换分支

git checkout <branch_name>

3)创建+切换分支

git checkout -b <branch_name>

4)查看分支

git branch

5)重命名分支

git branch -m <old_branch_name> <new_branch_name>

6)删除分支

git branch -d <branch_name>

7)合并分支

一般情况下,不会在master分支上进行修改,而是在其他分支上修改之后,合并到master分支中,这时候就需要进行分支合并。merge就是把其他分支或者commit的修改合并到当前分支上。 

git merge <branch_name> #将branch_name合并到当前分支
git merge --squash <branch_name> #不保留其他分支之前commit的历史,需要额外的一条commit;判断是否使用--squash选项最根本的标准是,待合并分支上的历史是否有意义。
git merge --no-ff #将当前分支上生成一个新节点而不是仅仅将指针进行转移

8)解决冲突

在分支合并时,如果不出现冲突,那么就会直接合并,如果出现冲突,git会提示,这时候必须手动解决冲突。

例如说在dev分支上提交了对A文件的新的修改,但master分支也提交了对A文件的新的修改。就是如下的情况

解决冲突:

打开冲突的文件,会发现git已经用Git用<<<<<<<,=======,>>>>>>>标记出不同分支的内容。此时需要以下步骤解决冲突:

    步骤一:修改冲突文件后保存

    步骤二:将文件add进暂存区,然后commit提交到版本库

    步骤三:进行merge操作

此时分支图就变成了如下:

也可以用以下命令查看分支情况

git log --graph
  • .gitignore

https://www.cnblogs.com/youyoui/p/8337147.html

Git远程仓库操作

  • clone

相当于把远程仓库克隆一份拷贝到本地

git clone <url> 
  • fetch

git fetch

上面命令将某个远程主机的更新,全部取回本地。默认情况下,git fetch取回所有分支的更新。如果只想取回特定分支的更新,可以指定分支名,如下所示 

git fetch <远程主机名> <分支名>
  • pull

当远程仓库有了更新后,我们就需要更新本地代码。

更新并合并

git pull <远程主机名> <远程分支名>:<本地分支名>
  • push

和pull相反,将本地commit的代码更新到远程版本库中 (第一次推送需要加-u参数)

git push origin <branch-name>

git push 一般需要先git pull 保证获取了最新的代码,然后再上传合并。 

Git团队协作

  当我们要给一个项目添加代码,但是它的主分支master不允许修改时,或者非此项目中的开发人员,想贡献代码。这个时候,最好的方式就是pr –pull request

pull request的意思实际上是请求远程仓库管理者处理你的提交(merge或不做改变)。

这里介绍一个github上pr的流程:

  这里我用C代表线上代码Repository的拥有者,D代表开发者

  1. fork、clone C的Repository到D的本地库

    这里的clone并不是简单的直接clone git上的代码到本地,而是先在网页端fork C的Repository到D的GitHub;

    然后D打开刚才fork过来的Repository,再使用git clone克隆代码到本地库。

  2. 与C在GitHub上的Repository建立新的链接

    使用

    git remote -v 

    命令查看一下D的本地库与哪些远程库建立了链接:会发现只与D在GitHub的Repository建立了链接,很显然没有与C在GitHub上的Repository建立链接,如下图: 

    接下来使用命令与C在GitHub上的Repository建立链接

    git remote add upstream <url>
  3. 开发并提交到D的远程库

    在本地库新建分支,并在新的分支完成开发,并add、commit、push到D的远程库(注意这里是push到D自己的github的Repostory)

    git chechout -b D-branch
    git add .
    git commit -m "comment"
    git push origin D-branch
  4. 发起PR

    在GitHub上发起pull requests请求,请求C进行review、merge等操作。

常见的PR合作流程与GitHub略有不同

无需fork,直接clone,新建分支写代码,然后在测试平台提PR。

git clone ssh://****  (代码目录)

git chechout -b mybranch    

git add src/main

git commit -m"[fix]   " 
[add] [merge] [fix]

git push origin mybranch

实际场景1:

拉取master分支,新建dev分支开发新功能,然后需要去修bug,这时候可以使用git stash暂存当前dev分支的工作内容。然后切回master分支创建bug修复分支修改bug,修改完后,切回dev分支 git stash pop,然后pull最新的master代码合并。

https://www.cnblogs.com/yanghaizhou/p/5269899.html

实际场景2:

拉取远程某一分支到本地(本地没有该分支) 

git checkout -b <branch_name> origin/<branch_name>

注意此处不能使用pull,此命令直接将远程分支拉下并和本地分支merge了 

git pull origin <branch_name>

实际场景3:

远程分支已经提交了几个commit了,但是本地退回了,想把退回的版本信息提交到远程。
这种情况会提示不让退回,提示远程版本已经领先了几个commit[not-fast-forwarded],这时候使用git push -f 即可强制提交,远程库版本就同时回滚了。

实际场景4:

  .gitignore无法对已经被add到暂存区的文件生效。这时候可使用

git rm -r --cached <file>

删除已经被加到暂存区的文件。

Reference

https://www.liaoxuefeng.com/wiki/0013739516305929606dd18361248578c67b8067c8c017b000

https://blog.csdn.net/qq_33429968/article/details/62219783

 

posted @ 2018-11-25 16:58  Allegro  阅读(390)  评论(0编辑  收藏  举报