前言:对于刚接触git或者一开始借助图形化git客户端的同学来说,在项目正常的拉取合并,或者代码冲突合并因为对于命令行认知较少经常会感到困扰,特别是在代码合并,特定分支管理的时候战战兢兢.本文整理了在工作中遇到git问题的汇总,之前经常是在用到相关指令才去查找.遂整理一番,方便学习和后续的工作查询.
一.git的工作流程
仓库:
1.Remote:远程主仓库
2.Repository:本地仓库
3.Index or stage:暂存区
4.workspace:工作区(即你本地编辑器的代码)
二.git add 提交到暂存区,出错怎么办?
一般代码提交流程为:
工作区 -> git status 查看状态 -> git add . 将所有修改加入暂存区-> git commit -m "提交描述" 将代码提交到 本地仓库 -> git push 将本地仓库代码更新到 远程仓库
场景1:工作区
//丢弃工作区的修改
git checkout --<文件名>
场景2:暂存区
当你不但改乱了工作区某个文件的内容,还 git add 添加到了暂存区时,想丢弃修改,分两步,第一步用命令 git reset HEAD ,就回到了场景1,第二步按场景1操作。
// 把暂存区的修改撤销掉(unstage),重新放回工作区。
git reset HEAD <文件名>
三.git commit 提交到本地仓库,出错怎么办?
1. 提交信息出错
更改 commit 信息
git commit --amend -m“新提交消息”
2. 漏提交
commit 时,遗漏提交部分更新,有两种解决方案:
(1)方案一:再次 commit
git commit -m“提交消息”
此时,git上会出现两次commit
(2)方案一:遗漏文件提交到之前 commit 上
git add missed-file // missed-file 为遗漏提交文件
git commit --amend --no-edit
--no-edit 表示提交消息不会更改,在 git 上仅为一次提交
3. 提交错误文件,回退到上一个 commit 版本,再 commit
git reset
删除指定的 commit
// 修改版本库,保留暂存区,保留工作区
// 将版本库软回退1个版本,软回退表示将本地版本库的头指针全部重置到指定版本,且将这次提交之后的所有变更都移动到暂存区。
git reset --soft HEAD~1
// 修改版本库,修改暂存区,修改工作区
//将版本库回退1个版本,不仅仅是将本地版本库的头指针全部重置到指定版本,也会重置暂存区,并且会将工作区代码也回退到这个版本
git reset --hard HEAD~1
// git版本回退,回退到特定的commit_id版本,可以通过git log查看提交历史,以便确定要回退到哪个版本(commit 之后的即为ID);
git reset --hard commit_id
git revert
撤销 某次操作,此次操作之前和之后的commit和history都会保留,并且把这次撤销作为一次最新的提交
// 撤销前一次 commit
git revert HEAD
// 撤销前前一次 commit
git revert HEAD^
// (比如:fa042ce57ebbe5bb9c8db709f719cec2c58ee7ff)撤销指定的版本,撤销也会作为一次提交进行保存。
git revert commit
git revert是提交一个新的版本,将需要revert的版本的内容再反向修改回去, 版本会递增,不影响之前提交的内容
git revert 和 git reset 的区别
(1):git revert是用一次新的commit来回滚之前的commit,git reset是直接删除指定的commit。
(2):在回滚这一操作上看,效果差不多。但是在日后继续merge以前的老版本时有区别。因为git revert是用一次逆向的commit“中和”之前的提交,因此日后合并老的branch时,导致这部分改变不会再次出现,但是git reset是之间把某些commit在某个branch上删除,因而和老的branch再次merge时,这些被回滚的commit应该还会被引入。
(3):git reset 是把HEAD向后移动了一下,而git revert是HEAD继续前进,只是新的commit的内容和要revert的内容正好相反,能够抵消要被revert的内容。
四.常用命令
1.初始开发 git 操作流程
(1):克隆最新主分支项目代码 git clone 地址
(2):创建本地分支 git branch 分支名
(3):查看本地分支 git branch
(4):查看远程分支 git branch -a
(5):切换分支 git checkout 分支名 (一般修改未提交则无法切换,大小写问题经常会有,可强制切换 git checkout 分支名 -f 非必须慎用)
(6):将本地分支推送到远程分支 git push <远程仓库> <本地分支>:<远程分支>
2. git fetch
将某个远程主机的更新,全部/分支 取回本地(此时之更新了Repository)它取回的代码对你本地的开发代码没有影响,如需彻底更新需合并或使用git pull
3.git pull
拉取远程主机某分支的更新,再与本地的指定分支合并(相当与fetch加上了合并分支功能的操作)
4.git push
将本地分支的更新,推送到远程主机,其命令格式与git pull相似
5.分支操作
(1):使用 Git 下载指定分支命令为:git clone -b 分支名仓库地址
(2):拉取远程新分支 git checkout -b serverfix origin/serverfix
(3):合并本地分支 git merge hotfix:(将 hotfix 分支合并到当前分支)
(4):合并远程分支 git merge origin/serverfix
(5):删除本地分支 git branch -d hotfix:(删除本地 hotfix 分支)
(6):删除远程分支 git push origin --delete serverfix
(7):上传新命名的本地分支:git push origin newName;
(8):创建新分支:git branch branchName:(创建名为 branchName 的本地分支)
(9):切换到新分支:git checkout branchName:(切换到 branchName 分支)
(10):创建并切换分支:git checkout -b branchName:(相当于以上两条命令的合并)
(11):查看本地分支:git branch
(12):查看远程仓库所有分支:git branch -a
(13):本地分支重命名: git branch -m oldName newName
(14):把修改后的本地分支与远程分支关联:git branch --set-upstream-to origin/newName
(15):拉取远程分支并创建本地分支:git checkout -b newBranch origin/remoteBranch
(16):从某一次commitID去创建新分支开发:git checkout -b newBranch commitId
6.git cherry-pick
对于多分支的代码库,将代码从一个分支转移到另一个分支是常见需求。
这时分两种情况。一种情况是,你需要另一个分支的所有代码变动,那么就采用合并(git merge)。
另一种情况是,你只需要部分代码变动(某几个提交),这时可以采用 cherry pick。
1.基本用法
git cherry-pick命令的作用,就是将制定的提交(commit)应用于其他分支
git cherry-pick
上面命令就会将指定的提交commitHash,应用于当前分支。这会在当前分支产生一个新的提交,当然它们的哈希值会不一样。
举例来说,代码仓库有master和feature两个分支。
a - b - c - d Master
\
e - f - g Feature
现在将提交f应用到master分支。
# 切换到 master 分支
$ git checkout master
# Cherry pick 操作
git cherry-pick f
上面的操作完成以后,代码库就变成了下面的样子。
a - b - c - d - f Master
\
e - f - g Feature
从上面可以看到,master分支的末尾增加了一个提交f。
git cherry-pick命令的参数,不一定是提交的哈希值,分支名也是可以的,表示转移该分支的最新提交。
git cherry-pick feature
上面代码表示将feature分支的最近一次提交,转移到当前分支。
2.转移多个提交
Cherry pick 支持一次转移多个提交。
git cherry-pick
上面的命令将 A 和 B 两个提交应用到当前分支。这会在当前分支生成两个对应的新提交。
如果想要转移一系列的连续提交,可以使用下面的简便语法。
git cherry-pick A..B
上面的命令可以转移从 A 到 B 的所有提交。它们必须按照正确的顺序放置:提交 A 必须早于提交 B,否则命令将失败,但不会报错。
注意,使用上面的命令,提交 A 将不会包含在 Cherry pick 中。如果要包含提交 A,可以使用下面的语法。
git cherry-pick A^..B
3.代码冲突
如果操作过程中发生代码冲突,Cherry pick 会停下来,让用户决定如何继续操作。
(1)--continue
用户解决代码冲突后,第一步将修改的文件重新加入暂存区(git add .),第二步使用下面的命令,让 Cherry pick 过程继续执行。
git cherry-pick --continue
(2)--abort
发生代码冲突后,放弃合并,回到操作前的样子。
(3)--quit
发生代码冲突后,退出 Cherry pick,但是不回到操作前的样子。
6.暂存
git stash 可以用来暂存当前正在进行的工作,开发中想pull最新代码又不想commit,或者为了修改一个紧急bug ,先stash,然后返回到上一个######commit,改完bug然后提交完代码后在git stash pop(弹栈)然后继续之前的工作, 如果修改的是同一个文件,则需要比较差异.
添加缓存栈: git stash ;
添加缓存栈: git stash save "save messge"; ----执行存储时,添加备注.
查看缓存栈: git stash list ;
推出缓存栈: git stash pop ;
清除所有缓存栈: git stash clear ;
清除指定缓存栈: git stash drop stash@{1};
取出特定缓存内容: git stash apply stash@{1} ; ---应用某一个存储
参考
https://juejin.im/post/5d5d61e96fb9a06ace5254bd#heading-26
http://www.ruanyifeng.com/blog/2020/04/git-cherry-pick.html
https://blog.csdn.net/yxlshk/article/details/79944535