git操作全系列汇总&备忘录

准备工作

git clone url / ssh   从github中下载项目

git config  --global user.name "pomelott" 配置本机的全局用户名为 pomelott

git config --global user.email  "pomelott@163.com" 配置本机的全局用户的邮箱为  pomelott@163.com

git config --global user.name / user.email 查看用户名/邮箱

git config --list  查看配置项列表

ssh-keygen -t rsa -C "xxx@xxx.com" -f ~/.ssh/id_rsa.gitlab 在指定文件生成ssh key

项目开发

git status 查看当前工作区与暂存区状态

git add  index.html 将文件从工作区提交到暂存区

git add --patch index.html 使用交互式暂存为部分代码做暂存

git add .  将修改过的文件全部提交到暂存区

git reset HEAD index.html  将提交至暂存区的文件撤回至工作区

git commit   将暂存区内容提交到版本库

git commit -m "注释"  提交到版本库时,直接在命令行添加注释

git commit -a -m "注释" 连续将修改的文件从工作区提交至暂存区再提交至版本库

重命名

git mv -f oldfolder newfolder

工作区、暂存区、版本库 内容的区别

git diff 显示工作区与暂存区的不同

git diff --cache(staged) 显示暂存区与版本库的不同

git diff master(当前分支名称) 显示工作区与本地版本库的不同

git diff origin/master 显示工作区与远程仓库不同

git diff commit-id [ <path>… ] :比较工作区与指定commit-id的差异

git diff --cached [ <commit-id> ] [ <path>… ] :比较暂存区与指定commit-id的差异

git diff [ <commit-id> ] [ <commit-id> ] :比较两个commit-id之间的差异

节点的父子关系表示法:^ 与 ~

  • ^:表示第几个父/母亲 —— git存在多个分支合并的情况,所以不只有1对父母亲
  • ~:表示向上找第几代,相当于连续几个 ^
G   H   I   J
  /      /
  D   E   F
     |  / 
     | /   |
     |/    |
      B     C
          /
         /
         A
A =      = A^0
B = A^   = A^1     = A~1
C = A^2  = A^2
D = A^^  = A^1^1   = A~2
E = B^2  = A^^2
F = B^3  = A^^3
G = A^^^ = A^1^1^1 = A~3
H = D^2  = B^^2    = A^^^2  = A~2^2
I = F^   = B^3^    = A^^3^
J = F^2  = B^3^2   = A^^3^2


撤销

git checkout -- filename.js  把工作区文件还原至版本库中的状态

git checkout -- .

git commit --amend 【注意不要在已经push到线上的情况下使用】修改上次提交信息

git commit -a filename --amend  修改上次的提交

* git reset 修改HEAD所指向的分支的指向, git checkout 修改HEAD的指向

git reset HEAD filiename.js   从暂存区撤销到工作区

运行 git reset file.txt(这其实是 git reset --mixed HEAD file.txt 的简写形式,因为你既没有指定一个提交的 SHA-1 或分支,也没有指定 --soft 或 --hard),它会:

1. 移动 HEAD 分支的指向 (已跳过)
2. 让索引看起来像 HEAD (到此处停止)

所以它本质上只是将 file.txt 从 HEAD 复制到索引中。

  • --soft – 缓存区和工作目录都不会被改变
  • --mixed – 默认选项。缓存区和你指定的提交同步,但工作目录不受影响
  • --hard – 缓存区和工作目录都同步到你指定的提交

git reset --filename 对某一指定的文件撤销git add 操作

git reset [hash] 撤销至指定hash版本,并且对应hash版本的后续记录全部清除【需要慎重使用】当提交至远程库时,因落后于远程库,所以需要使用git push -f进行对应提交

git reset --hard origin/master 撤销当前工作区所有更新至远程分支master的最新版本 【需要慎重使用】

git reset --hard id 恢复至某一指定版本(对应版本之后的提交会被删除)

git reset --hard HEAD 撤销工作目录中所有未提交文件的修改内容

git revert [hash] 重新操作指定hash版本,工作区内容会还原至指定版本的上一个版本,可能会存在冲突。

git revert -m 1   其中1是错误合并后 撤销至主线mainline需要保存的的父节点索引,在合并时所在分支上的父节点为1

reset与revert的区别:

1.  reset操作删除指定提交之后的所有提交,若在最新提交与指定提交期间存在新建的分支,则新建的分支不受影响;revert操作为重写指定提交之后的所有提交,并创建一个新的提交。revert后的内容为对应提交的父提交的内容。

2. reset不保留提交历史, revert保留提交历史。

3. reset为HEAD指针对应的分支向后移动,指向相应的提交; revert为向前移动,并创建新的提交。

 

死亡恢复(分支已被删除,log全无)

git reflog 找到指定的commitID

git checkout commitID 回到指定commit的状态,但当前HEAD处于分离式状态

git checkout -b reflog_revert_branch_name 将状态用新建的分支保存下来并指定分支名

git checkout working_branch 切换回原工作分支

git merge reflog_revert_branch_name 将恢复分支并入工作分支

至此恢复基本完成,但剩余的临时分支reflog_revert_branch_name应删掉, git branch -D reflog_revert_branch_name

如果你已经发布了临时分支,并且希望从远程仓库删除它 git push -D reflog_revert_branch_name
 

删除

git rm filename  将暂存区中的文件删掉(必须在工作区中删除了相应的文件后,此命令才有效)

git rm -f filename  将工作区和暂存区中对应的文件全部删除

git rm --cached filename 将暂存区中对应的文件删除,保留工作区中对应的文件

记录

git log 查看提交日志(查看版本ID)

git log --pretty=oneline --graph  单行展示带表格

git log --name-only 查看提交对应修改的文件

git log --pretty=short --graph 简短(hash + author + graph)

git log --cc 查看带有冲突的log记录

git log --grep="up" 搜索log的提交信息中带有up的提交

git log -g  以标准日志的格式输出引用日志(reflog)

git log --author="tate"  根据提交用户过滤

git log -L 1,100:TUtil.js  查看1-100行对应文件中提交内容的日志

git log -L :funName:FileName 查看对应函数中的提交记录(非C语言需要自定义配置)

git blame -L 1,50 index.js 查看index.js文件中,1-50行代码的每一行是谁写的(谁首次添加的)

* 双点和多点语法可用在log和diff中

git log master..experiment  在 experiment 分支中而不在 master 分支中的提交

git checkout  id(部分即可) 文件名 迁出、恢复(某一版本的指定文件)

git log origin/Damon..HEAD  当前分支正在跟踪远程分支Damon,此命令可以查看在当前分支中,但不在远程分支origin/Damon中的提交

查看远程分支的log

$ git log origin/master
$ git log remotes/origin/master
$ git log refs/remotes/origin/master
Git 允许你在任意引用前加上 ^ 字符或者 --not 来指明你不希望提交被包含其中的分支。因此下列3个命令是等价的:
$ git log refA..refB
$ git log ^refA refB
$ git log refB --not refA
查看所有被refA 或 refB 包含的但是不被 refC 包含的提交,你可以输入下面中的任意一个命令:
$ git log refA refB ^refC
$ git log refA refB --not refC
master 或者 experiment 中包含的但不是两者共有的提交:
$ git log master...experiment

git reflog  查看操作历史,以确定回到哪个版本

git show [SHA-1] 查看某次提交的详细信息

查看仓库中 HEAD 在五次前的所指向的提交:
$ git show HEAD@{5}
查看某个分支在一定时间的提交信息(这个方法只对还在你引用日志里的数据有用,所以不能用来查好几个月之前的提交)
$ git show master@{yesterday}
$ git show HEAD@{2.months.ago}
使用 HEAD^ 来查看上一个提交,也就是 “HEAD 的父提交”:
$ git show HEAD^
在 ^ 后面添加一个数字——例如 d921970^2 代表 “d921970 的第二父提交”这个语法只适用于合并(merge)的提交,因为合并提交会有多个父提交。第一父提交是你合并时所在分支,而第二父提交是你所合并的分支:
git show d921970^2  

通过git探测器获取SHA-1

$ git rev-parse topic1
ca82a6dff817ec66f44342007202690a93763949

 调用交互式暂存:

git add -i/--interactive 启动交互式暂存

储藏与清理:

当需要暂时修改工作环境,但又不希望单独对已修改内容进行提交。可使用stash进行命令

git stash 对当前工作区修改内容进行存储

git stash list 查看已存储stash

git stash apply 应用所有已存储stash

git stash apply stash@{0} 对指定名称stash进行应用

git stash drop stash@{0} 移除对应的储藏

git stash pop stash@{0} 应用对应的储藏并移除

git clean -fd  移除所有未保存的变更,主要指未被跟踪的文件

查找

git grep -n testfn  查找testfn,并根据行号展示

git grep -n testfn -- '*.js' 只在js文件中查找testfn

  

将本地版本库同步到github

首先需要确定本地github登陆的账号与需要提交更新的远程github账户一致

git remote 查看远程仓库的名字(默认为origin)

git remote -v  查看远程仓库的地址

git  push  远程仓库名字(默认为origin)  分支(默认为master) 将本地版本库同步至远程仓库

多人协作时需要首先为项目成员分配权限

可通过git config --global user.name 与 git config --global user.email 修改git工具的用户

然后在本地github上登陆新的用户

多人协作冲突解决

1. git fetch

拉取请求后不与当前分支合并,需手动合并【推荐】,一般起冲突后说明不同开发人员更改了同一部分内容,需先拉取请求后查看冲突区域

git  diff  master  origin/master 可查看冲突区域

git  merge  origin/master 合并冲突后再文件中查看起冲突的不同代码片段,将更有效的代码保留,删除无效的代码。

git  commit -a -m "注释"  提交到本地版本库

git  push  origin  master 再提交至远程仓库

2. git Pull

拉取请求后直接与当前分支合并,显示的为远程仓库中最新的版本

开源项目协作方式

点击分支fork,在自己的账户下建立开源项目的镜像

glt clone 地址,克隆到本地修改后再通过 git add 与git commit 提交到个人用户的github上

然后进行pull request向开源项目拥有者发起拉请求

  

git分支处理

git branch -a 查看分支列表

git remote -v 查看本地分支对应的远程地址

分支常用于大型项目的多人协作开发,每一个项目成员首先在不同的分支上进行开发,最后再将多个分支合并到主分支即可。

首先可以用git branch查看分支

创建新分支 git branch newbranch(新分支的名字)

切换至新分支 git chechout newbranch

(快速创建分支并切换分支 git checkout -b newbranch2)

git branch -d branchName 删除对应的分支

git push origin --delete branchName 删除对应的远程分支

变基(会将变基时所在的分支节点在末尾并入)

git rebase origin/master  将当前分支的所有提交记录追加至远程分支origin/master中

git rebase --onto branch1 branch2 将在分支2中且不在分支1中的内容rebase至当前分支

在需要优化提交历史,使其变得简单明了的时候首选rebase,但需要遵循黄金法则,即不在共享的分支上使用rebase

使用变基的场景:

1. 保持一个分支最新

2. 发布工作前,交互式变基允许你将提交安排成易于阅读的历史记录。

多人协作分支操作建议

1. 完成功能分支之后先不 merge,而是回到主干分支去 git pull --rebase

2. 如果主干有更新,rebase 更新的内容到功能分支来预检一下,看看在加入了最近别人的改动之后我的功能是否依然 OK(在这个过程中可能会有冲突处理,别怪我没提醒哦)

3. 一切就绪之后再次 git fetch 主干看看有没有变动(因为在第二步的进行期间没准又有人 push 了新的变化),有的话重复第二步,没有则——

4. 合并功能分支到主干然后 push。

分支合并

合并后可在master分支下使用:git branch --merged   查看当前分支下合并的分支

(另外可通过 git branch --no-merged 查看未合并的分支)

当前状态是master与newbranch合并,newbranch已经无效,可通过git branch -d newbranch进行删除(此方法只能删除当前分支下合并后的分支)

若要强制删除未合并的分支可用 git branch -D newbranch2

git merge --squash  使用squash方式合并,把多次分支commit历史压缩为一次

git merge --abort 选项会尝试恢复到你运行合并前的状态。但当运行命令前,在工作目录中有未储藏、未提交的修改时它不能完美处理,除此之外它都工作地很好。

git merge --no-ff  强制关闭fast-forward合并后本地分支的commit不会被并入,规范化管理分支与主干的情况下很有必要使用(fast-forward方式就是当条件允许的时候,git直接把HEAD指针指向合并分支的头)

要在合并前比较结果与在你的分支上的内容,换一句话说,看看合并引入了什么,可以运行 git diff--ours , 如果我们想要查看合并的结果与他们那边有什么不同,可以运行 git diff --theirs。

当分支冲突时,在master分支下使用git merge newbranch后会发生冲突提示(使用git status 可查看冲突文件),此时在冲突的文件下会显示冲突区域的不同代码,人为选择后删除不需要的代码再次提交 get commit -a -m  文件名即可完成合并,可通过git branch --merged查看合并后的分支。

git reset --merge ORIG_HEAD (当没有产生新的ORIG_HEAD时) 或 git reset commitID 撤销合并
 
撤销合并之前,手下考虑如何找回丢失的提交具,思路如下:

当其他人把已经撤销的合并并入远程仓库时,会把它们视为新的提交。此处就涉及到如何撤销共享仓库的合并。
当你将一个(过时的)分支并入主仓库时,你就会遇到这种情况。如下图,快进合并会先进行变基,不利于后去撤销合并:

 如下图,根据分支的合并方式,需要使用不同的命令来撤销共享分支的合并:

  

发布版本(打标签)

进入想要打标签的分支

git tag v1.0 为当前分支设定版本为1.0

git tag  查看所有版本

git push origin v1.0 将标签同步到远程仓库

  

小技巧:

定义指令:git config --global alias.co commint 用co代替commint命令,直接git co就可以

可用git config --list查看配置

git gc --prune=now 运行垃圾回收器并确保所有未提交的变更从本地内存中移除
原文地址:https://www.cnblogs.com/pomelott/p/7078379.html