learngitbranch试炼场(感谢这个试炼场解决了我git恐惧症)

基础篇

git commit

git commit -m ""将暂存区的所有修改提交至仓库。HEAD向前移动一个单位,如果HEAD指向了一个Branch指针,那么这个Branch指针会向前移动,HEAD继续指着这个Branch
git commit --amend修改这次提交(不产生记录,只修改当前提交的记录)

git branch

git branch bugFix用于在HEAD处创建一个名为bugFix的分支指针
git branch -f bugFix c3强制将bugFix分支指针指向c3
git branch -u origin/main foo 将foo关联远端的main分支(如果当前在foo分支上,甚至可以直接省略这个foo)
git branch -vv查看所有本地分支对应的远程分支
git branch查看所有本地分支
git branch -r查看所有远程分支
git branch -a查看所有分支,包括远程分支
git branch -d fixBug删除某个指定的分支

git checkout

git checkout s87d用于将HEAD指向对应位置的提交(HEAD分离状态)
git checkout HEAD^用于将HEAD指向HEAD前一个提交(若多父节点HEAD^1``HEAD^2可以选择指向第几个父节点)
git checkout HEAD~2用于将HEAD指向HEAD前第二个提交(相对移动可以混用,如HEAD^2~3^^
git checkout bugFix用于将HEAD指向bugFix指针处
git checkout -b bugFix用于在当前HEAD处创建一个分支指针并将HEAD指向它
git checkout -b bugFix c2用于在c2处创建一个分支指针并将HEAD指向它
git checkout -b bugFix origin/master在HEAD处创建一个新分支bugFix,并关联到远程仓库的master分支上(pull拉下来后就会自动合并这个分支和origin/master,push的话)

git merge

git merge bugFix创建一个HEAD与bugFix的公共子节点,然后HEAD指向这个子节点(就是会有一个多的merge记录的节点)类似合并
下图演示的是不可以fast forward的合并:
image.png
image.png
fast forward的合并,可以用于移动分支指针指针

git rebase

git rebase main将当前分支的所有修改直接移入main分支后面,看起来就是顺序开发的,用于解决merge不好看的问题(注意,提交记录 C3 依然存在(树上那个半透明的节点),而 C3’ 是我们 Rebase 到 main 分支上的 C3 的副本)类似移动
image.png
如果是可以fast forward的rebase,那就相当于将分支移到最新处
image.png
git rebase main bugFix将main上面的所有修改移动至bugFix上,这样可以省去checkout到main上再rebase bugFix的复杂操作
git rebase -i用于可视化复制分支,可以对分支的顺序进行调整,甚至可以选择不复制某一些分支,如图git rebase -i c1,将当前分支的修改复制到c1提交下,一般用于调整一下分支的记录
image.png

git reset

这是一个后悔药,可以用git reset跳到某一次提交(注意,如果不加参数从c2跳入c1,c2的修改会存在于本地(未加入暂存区,即还没有add),需要加入参数--hard跳转或者执行git checkout .将所有的文件从当前的提交检出),然后git log出来的话c2提交会像看不到一样,需要用git reflog将历史操作打印出来,再次reset即可跳回
image.png

git revert

这是一个后悔药,你可以用该命令反做某一次提交,如git revert HEAD将目前版本的修改全部逆向操作,生成一个新的版本,一般用于需要同步远程的分支
image.png

git cherry-pick

这是一个分支调整指令,用于将指定的提交复制到当前HEAD修改下,然后将HEAD向下移动,如git cherry-pick c2 c4
image.png

git tag

对某一次提交打上永久的tag,一般是一次重大的更新或者bug修复
image.png

git describe

由于标签在代码库中起着“锚点”的作用,Git 还为此专门设计了一个命令用来描述离你最近的锚点(也就是标签),它就是 git describe,使用如下图
image.png

远程篇

git clone

克隆某一个仓库,本地与线上完全一样,本地会出现远程分支(origin/master之类的),checkout该远程分支会自动进入HEAD分离状态,因为该远程分支指针只负责记录上次和服务器通讯时的状态,commit不能使该分支向前移动

git fetch

将线上仓库同步下来(所有的与本地不同的分支都会被同步下来)
image.png
image.png
原理
image.png
fetch后就可以手动处理合并了
image.png
当然,强大的git也会让你可以指定fetch远程的哪一个分支到本地的哪一个分支上
git fetch origin foo下载远端foo分支,更新至本地的origin/foo分支上
git fetch origin <source>:<destination>下载远端的source资源,更新到指定分支,如git fetch origin master^:foo这会将远端master前一个的所有修改同步到本地的foo分支(注意不是origin/foo分支,因为命令直接指定了分支名)

git pull

建议单独使用git fetchgit merge,不然容易混乱,除非你知道这条命令会有啥结果
git pull是默认的操作,他会先fetch,然后用merge指令合并所有已跟踪分支,如master->origin/master
git pull --rebase先fetch,然后用rebase合并已跟踪分支
image.png
git pull origin foo指定拉取某一个远程分支,等价于git fetch origin foo; git merge origin/foo,现在远程拉下foo分支至origin/foo分支(没有则创建),然后用origin/foo分支和当前的分支合并!注意!这里不是让foo和origin/foo合并,而是origin/foo和当前分支合并
git pull origin <source>:<destination>:指定从远端下载哪个分支到本地的哪个分支再和当前检出分支合并,例如git pull origin foo:bugFix将远程的foo下载到本地的bugFix分支(没有则创建),然后将本地的bugFix和当前分支合并

git push

推送当前的分支至服务器(推送到服务器上的哪个分支是可选的,用-u记录下当前的选择,下次push该分支将会自动推送到对应位置),如下:
image.png
image.png
git push origin master,将本地的master分支推上远端的master分支,若需要加上该本地分支的跟踪,可执行git push -u origin master边推送边设置远程分支跟踪,如果不想本地master推送到远程的master分支,可以用该指令指定要推送到远程的哪个分支git push origin <source>:<destination>,如git push origin foo:main,将本地的foo推送到远端的main分支

git push --delete origin fixBug:删除服务器上的fixBug分支,作此步骤前一定要先删除对应本地分支(好像也有资料写的是可以不删?)

提交历史偏移

核心思想是git远程仓库只允许新增线条,不允许删除,如下面这种情况,若要让远程仓库和本地一样,只能删掉远程中c1->c2的代码,显然不被允许
image.png
解决方法,push前现在本地解决好冲突,即先fetch+rebase(可以合起来变成一个pull —rebase指令),然后向上推送
image.png
image.png
这样子远程就只是多了一条线,不会删除线,满足我们的要求
当然,merge也能满足我们的要求,如下
image.png
image.png

跟踪远程分支

需要对某一个分支设定它对应需要跟踪的远程分支,git push才能push到对应位置,没有对应的远程分支的话,需要直接执行git push origin master才能推送上去,若需要加上该本地分支的跟踪,可执行git push -u origin master边推送边设置远程分支跟踪,如果不想本地master推送到远程的master分支,可以用该指令指定要推送到远程的哪个分支git push origin <source>:<destination>,如git push origin foo:main,将本地的foo推送到远端的main分支
设定跟踪有几种方法

  • checkout时通过-b选项指定
  • branch时通过-u选项指定
  • git push -u origin master-u指定本地master分支跟踪远程master分支

    git提交message标准

  • feat:新功能(feature)

  • fix:修补bug
  • docs:文档(documentation)
  • style: 格式(不影响代码运行的变动)
  • refactor:重构(即不是新增功能,也不是修改bug的代码变动)
  • test:增加测试
  • chore:构建过程或辅助工具的变动

    疑难杂症

    删除了远程分支,如何将这个信息同步至本地
    git remote prune origin
    本地删除了分支,如何同步至远程

    删除远程分支

    git push --delete bugFix
    假设你已经通过远程分支做完所有的工作了——也就是说你和你的协作者已经完成了一个特性, 并且将其合并到了远程仓库的 master 分支(或任何其他稳定代码分支)。 可以运行带有 —delete 选项的 git push 命令来删除一个远程分支。 如果想要从服务器上删除 serverfix 分支,运行下面的命令:
    1. $ git push origin --delete serverfix
    2. To https://github.com/schacon/simplegit
    3. - [deleted] serverfix
    基本上这个命令做的只是从服务器上移除这个指针。 Git 服务器通常会保留数据一段时间直到垃圾回收运行,所以如果不小心删除掉了,通常是很容易恢复的。

    修改了本地文件没有commit如何恢复

    git checkout . 签出成当前分支最新的文件