git 常用操作汇总复习

作为一种功能强大的项目管理工具,git不仅能够实现方便的版本控制,还能够进行多人开发的项目管理。本篇博客主要汇总一些常用的git操作,作为笔者自己的复习巩固,亦作为读者之间的交流探讨。

1. 高频操作

  • git init: 初始化仓库,工作区多了一个.git目录用于存放仓库信息。
  • git add : 将工作区的改动存放到暂存区。可以指定文件名,也可以加-A参数,表示针对仓库所有文件。
  • git commit -m : 将当前暂存区存储的所有改动,存入一个commit。commit类似于一个快照/存档,你当然可以随意读档、存档。如果git commit出错了怎么办,参见笔者另一篇博客【git】git commit -m的message输错咋办。
  • git status: 查看当前仓库所有文件的状态。例如,哪些文件被改动了。并提供一些可能命令。
  • git diff :查看文件相对于最近一次暂存(上一次add)的改动。

2. 版本控制

所谓控制‘版本’,其实就是管理commit。

  • git reset --hard : 切换版本,不仅可以切换过去版本,还能从过去版本切换回来,只要你知道commit_id。commit_id不仅可以用绝对位置,还可以用HEAD指针表示的相对位置指代。例如,HEAD^表示上一个版本,HEAD^^表示上上个版本,HEAD~100表示前100个版本。
  • git log: 查看提交历史, 由近到远显示,仅包含commit命令,可以用来获取过去的commit_id。笔者喜欢加上一些参数使用git log --graph --pretty=oneline --abbrev-commit,效果如下:

git 常用操作汇总复习_第1张图片

  • git reflog: 查看命令历史,包括commit在内的所有历史命令及其id,可以用来获取未来的commit_id。

3. 修改管理

所谓管理‘修改’,指的是对工作区、暂存区修改的管理,而非针对于commit。管理commit参见上一节,版本控制。

  • git restore --staged : 将指定文件的改动,从暂存区撤回。相当于git add的逆操作。
  • git restore :将指定的文件的改动,从工作区撤回。相当于直接退回上个commit版本。
  • git stash:将当前工作区的状态保存。一般适用于,当前分支工作区的修改还未commit,需要切换分支进行其他操作(例如,修改其他分支的紧急bug)。此时,若不通过stash保存工作区,当前分支工作区的修改将丢失。
  • git stash list:查看所有保存的工作区。
  • git stash apply stash@\{0\}:将某个保存的工作区恢复到当前版本。此处,以序号0为例。注意,shell里面要用\转义{}
  • git stash drop stash@\{0\}:删除某个保存的工作区。
  • git stash popgit stash apply + git stash drop。使用前先确认,stash list顶端的那个工作区,是你要恢复的工作区。

4. 远程关联和同步

远程关联

如果想要将本地仓库push到远端,需要提前和远端仓库(例如,github的仓库)建立关联:

  • git remote add origin : 添加一个名为origin的远程库。origin是通用的仓库名称,也可以自定义。
  • git remote rm origin: 和origin解除关联,如果add的时候url错了。

如果想要从远端拉取一个仓库:

  • git clone : 将某个仓库拉取到本地,自动建立关联。推荐用ssh协议; 如何在远端添加本地机器的ssh密钥,详见笔者另一篇博客添加github ssh授权。

远程同步

  • git remote -v: 查看远程库地址信息。
  • git pull origin : 将远端origin仓库的src(一般为某个分支,如master),拉取到本地仓库。
  • git push origin : 将本地仓库的src(一般为某个分支,如master),推送到origin仓库。
  • git pull --rebase:rebase操作可以把本地未push的分叉提交历史整理成直线,但个人不建议使用。

有些时候,我们不想让某些文件被push到远程进行同步,比方说,vscode的配置文件,编译中间文件等。这个时候我们可以写一个.gitignore文件,将我们不想要加入git仓库的文件写入。这样,git在进行项目管理的时候,就会.gitignore中指定的那些文件。

笔者通常使用如下的.gitignore,用来忽略所有.开头的隐藏文件,.gitignore.gitkeep除外。

.*
!.gitignore
!.gitkeep

5. 分支管理

  • git branch:查看分支。当前分支前面会有*号。
  • git branch :创建分支。
  • git switch :切换分支。
  • git switch -c :创建+切换分支。
  • git merge : 合并某分支到当前分支。笔者喜欢在合并时,加上--no-ff参数,用以防止fast forward。
  • git branch -d :删除本地分支。如果被删除的分支还有未被merge的内容,需要强制指定-D删除。
  • git push origin --delete : 删除远程分支。
  • git cherry-pick :将某个特定的commit的改动,复制到当前分支。可以将其他分支的commit应用过来。cherry-pick的目的主要是为了防止重复劳动。使用场景,例如,发现master分支有bug,由于dev分支是fork自master,因此dev分支也需要相同的操作修复相同的bug。所以,在master分支修复bug之后,可以用cherry-pick,将master分支修复bug的那个commit直接apply到dev分支。也可以用在修改commit message,详见【git】git commit -m的message输错咋办。

6. 标签管理

一个标签和一个commit密切相关,标签存在的意义在于,commit_id不易于理解交流。因此,对于某些比较重要的commit,可以给其附上tag,方便定位、回溯和发布。

  • git tag:查看所有标签。
  • git tag : 给指定的commit,打一个指定名字的标签,例如,v1.0。若不指定 commit_id,默认打在当前分支,最新的一个commit上。
  • git show :查看指定标签信息,例如,commit_id。
  • git tag -a -m :使用 -m 还可以为这个tag附上额外的message。
  • git tag -d : 删除一个标签。

由于git push origin branch的时候,并不会将该branch的tag也push上去,所以本地的tag需要独立地push

  • git push origin : 推送某个标签到远程。
  • git push origin --tags: 一次性推送全部尚未推送到远程的本地标签。
  • git push origin :refs/tags/: 如果需要删除某个远端已经上传的标签,则需要先使用git tag -d 先把本地的标签删除,在使用该条命令,将标签删除操作,同步到远程。

7. 其他补充

  • git的精髓在于,它管理的是你文件的改动,而非文件本身。

  • commit在git版本管理中起到很重要的作用,合适的comment可以帮助你迅速定位和回溯。所以,不同commit之间尽量逻辑分明。在进行开发时,能add的改动就先add暂存起来,等到一个功能具体的、逻辑完整的改动完成之后,再commit。

  • git有工作区和暂存区之分。所谓工作区,就是指你本地的这个文件夹内的所有文件。工作区内的改动在你关掉IDE之后就没了(因为一旦断电,你就没办法ctrl+z,回溯到你之前的文件版本,你就不知道你改动的部分到底是啥);而git add就是将你工作区的改动暂存起来,便于你随时离开;而git commit则是将你所有暂存的改动,一次性存成一个正式的存盘,可以在以后随时回溯。
    git 常用操作汇总复习_第2张图片

  • git强烈建议多用分支。增加功能 / 修复bug,都建议新建一个分支,等完成任务之后merge到主分支,再删除新分支。

  • git的每个branch都有各自的指针,用于指向当前的commit id,指针值改变,commit版本就改变;git还有一个全局的环境变量–HEAD,用来指向当前分支的指针,HEAD的值改变,当前所在的分支也就改变。因此,git 版本 / 分支切换速度很快,因为git的版本 / 分支切换只是改变HEAD / 分支指针的值罢了。
    git 常用操作汇总复习_第3张图片

  • 在远端同步和分支合并的时候,很容易就出现conflicts。一般是由于相同的文件,被不同地修改,此时需要手动修理冲突,并进行额外的commit。Git用<<<<<<<=======>>>>>>>标记出冲突内容。

  • 引用廖雪峰的官方网站,针对多人协作,远程同步时,经常会出现conflicts,一般用以下原则应对:
    1.首先,可以试图用git push origin 推送自己的修改;
    2.如果推送失败,则因为远程分支比你的本地更新,需要先用git pull试图合并;
    3.如果合并有冲突,则解决冲突,并在本地提交;
    4.没有冲突或者解决掉冲突后,再用git push origin 推送就能成功!
    5.如果git pull提示no tracking information,则说明本地分支和远程分支的链接关系没有创建,用命令git branch --set-upstream-to origin/

  • git不仅可以帮助多人协作,就算是你自己平时本地开发,也可以用git方便的切换/回溯不同的版本(commit)

  • 根据笔者的经验,一般而言,我们在新开始写一个项目的时候,都会自然地把工作区初始化为一个git仓库,利用git便捷的版本控制系统来协助自己本地的开发。如果开发者只有自己,那可以等正式版本确定之后,再push到远程,不用每次commit一个存档,都push一次;当项目不止一个人参与时,就需要随时同步到远程仓库,和其他同伴进行协作,及时解决conflicts,这种情况下,最好commit一次,就push一次。

  • git本地的分支可以不推送到远端,完全看个人需要。

  • 引用廖雪峰的官方网站,在实际协同开发中,哪些分支我们需要时刻和远端保持更新呢?
    1.master分支是主分支,因此要时刻与远程同步;
    2.dev分支是开发分支,团队所有成员都需要在上面工作,所以也需要与远程同步;
    3.bug分支只用于在本地修复bug,就没必要推到远程了,除非老板要看看你每周到底修复了几个bug;
    4.feature分支是否推到远程,取决于你是否和你的小伙伴合作在上面开发。

  • 引用廖雪峰的官方网站,在实际协同开发中,我们应该按照几个基本原则进行分支管理:
    1.首先,master分支应该是非常稳定的,也就是仅用来发布新版本,平时不能在上面干活;
    2.那在哪干活呢?干活都在dev分支上,也就是说,dev分支是不稳定的,到某个时候,比如1.0版本发布时,再把dev分支合并到master上,在master分支发布1.0版本;
    3.你和你的小伙伴们每个人都在dev分支上干活,每个人都有自己的分支,时不时地往dev分支上合并就可以了。
    4.所以,团队合作的分支看起来就像这样:
    git 常用操作汇总复习_第4张图片

参考

本文主要参照廖雪峰的git教程,该教程还囊括了git服务器搭建,git命令别名,以及sourcetree的使用等,这里笔者强烈安利初学者进行学习。

  • 廖雪峰的官方网站

你可能感兴趣的:(git,git,github)