常用场景:
想想下列工作场景时候是你经常遇见的?
我们可能为了保持工作空间clean, 会commit多次,但是很多时候commit的内容是没有什么意义的. 这个时候我们需要合并commit.
领导叫我去另外一个分支去修改内容, 我要保存当前的分支的内容.
前几次提交的commit还没push, 我想回滚.
有些文件我不想提交到git仓库
合并或者修改coomit
有的时候我们提交commit 的备注的时候可能没有写备注,或者是备注写错了,这个时候我们需要修改commit, 这个时候--amend 计算非常有用了. 无论是否提交到远端服务器 git commit --amend 都可以修改最近一次的提交.
- 修改commit内容
一、如果已经push到远端服务器,想修改已经提交过的commit信息
1.保存:Ctrl + o; 回车 ;退出:Ctrl + x
# git commit --amend
2.重新提交gerrit审批
# git push --no-thin origin HEAD:refs/for/master
二、如果已经push到远端服务器,有漏掉的test.txt文件想提交到上一次的commit信息
1.添加test.txt
# git add test.txt
2.修改commit信息;保存:Ctrl + o; 回车 ;退出:Ctrl + x
# git commit --amend
3.重新push到远端服务器
# git push --no-thin origin HEAD:refs/for/master
- 合并commit
由于我们可能为了保持工作空间clean, 会commit多次,但是很多时候commit的内容是没有什么意义的. 这个时候我们需要合并commit.
被合并过的commit 是不能再次被合并的I
HEAD~ 后面表示最近多少次提交
git rebase -i HEAD~3
pick d6d290e 123123
pick 5c7ee5a 12321
pick 2e4ed64 12321
简单的解释一下:
前面三行是我们需要操作的三个 Commit,每行最前面的是对该 Commit 操作的 Command。关于每个 Command 具体做什么,下面的注释写得非常清楚。为了完成我们的需求,我们可以关注到这两个命令:
1. s, squash = use commit, but meld into previous commit
2. f, fixup = like "squash", but discard this commit's log message
翻译:
- squash:使用该 Commit,但会被合并到前一个 Commit 当中
- fixup:就像 squash 那样,但会抛弃这个 Commit 的 Commit message
看样子两个命令都可以完成我们的需求,那么让我们先试一下 squash!由于我们是想把三个 Commit 都合并在一起,并且使 Commit Message 写成 Commit-1,所以我们需要把 5c7ee5a(12321) 和 2e4ed64(12321) 前面的 pick 都改为squash,于是它看起来像这样:
pick d6d290e 123123
pick 5c7ee5a 12321
pick 2e4ed64 12321
#当然,因为我很懒,所以通常我会使用它的缩写:
pick d6d290e 123123
s 5c7ee5a 12321
s 2e4ed64 12321
然后执行 :wx ,保存. git又会打开合并备注的vim操作
# This is a combination of 3 commits.
# This is the 1st commit message:
123123
# This is the commit message #2:
12321
#### 后面的内容已经省略
这个时候我们就可以修改上面的备注, 然后执行 : wx.
然后查看提交记录:
git log
就会发现提交记录已经被合并了.
保存工作空间现场
在开发中,会经常碰到bug问题,那么有了bug就需要修复,在Git中,分支是很强大的,每个bug都可以通过一个临时分支来修复,修复完成后,合并分支,然后将临时的分支删除掉。
比如我在开发中接到一个bug时候,我们可以创建一个bug1分支来修复它,但是,当前的dev分支上的工作还没有提交。比如如下:
并不是我不想提交,而是工作进行到一半时候,我们还无法提交,比如我这个分支bug要2天完成,但是我bug1需要5个小时内完成(分支是可以提交的,不过增加了多余的commit信息, 这时候就可以使用stash 命令)。怎么办呢?还好,Git还提供了一个stash功能,可以把当前工作现场 ”隐藏起来”,等以后恢复现场后继续工作。如下:
git stash apply 恢复,恢复后,stash内容并不删除,你需要使用命令git stash drop来删除。
另一种方式是使用git stash pop,恢复的同时把stash内容也删除了。
需注意上面那句话所对作用范围的定义,如果你的文件没add,即没有“被跟踪”和“暂存”,stash是不会帮你保存的。
(1)git stash save "save message" : 执行存储时,添加备注,方便查找,只有git stash 也要可以的,但查找时不方便识别。
(2)git stash list :查看stash了哪些存储
(3)git stash show :显示做了哪些改动,默认show第一个存储,如果要显示其他存贮,后面加stash@{$num},比如第二个 git stash show stash@{1}
(4)git stash show -p : 显示第一个存储的改动,如果想显示其他存存储,命令:git stash show stash@{$num} -p ,比如第二个:git stash show stash@{1} -p
(5)git stash apply :应用某个存储,但不会把存储从存储列表中删除,默认使用第一个存储,即stash@{0},如果要使用其他个,git stash apply stash@{$num} , 比如第二个:git stash apply stash@{1}
(6)git stash pop :命令恢复之前缓存的工作目录,将缓存堆栈中的对应stash删除,并将对应修改应用到当前的工作目录下,默认为第一个stash,即stash@{0},如果要应用并删除其他stash,命令:git stash pop stash@{$num} ,比如应用并删除第二个:git stash pop stash@{1}
(7)git stash drop stash@{$num} :丢弃stash@{$num}存储,从列表中删除这个存储
(8)git stash clear :删除所有缓存的stash
回滚或者丢失不想要的内容
用Git的时候commit提交代码后,发现这一次commit的内容是有错误的,或者不想提交了,那么有两种处理方法:
1、修改错误内容,再次commit一次
2、使用git reset 命令撤销这一次错误的commit 第一种方法比较直接,但会多次一次commit记录。 我个人认为 第二种更加好点, 错误的commit就没有必要提交了.
- 如果你只是想撤销 commit, 但是保留 add. (此时文件的变动也会被保留)
git reset --soft HEAD^
注意了: HEAD^ 上个版本,HEAD~2 上上个版本miced commitId
- 删除工作空间改动代码,撤销commit,撤销git add
git reset --hard HEAD^
- 不删除工作空间改动代码,撤销commit,并且撤销git add(常用)
git reset --mixed HEAD^ 或者git reset HEAD^
- 还没有commit, 但是已经 add. , 只想撤销 add
-- filename 是指单个文件名
git reset HEAD filename
全部:git reset HEAD
- 不想保留本地文件的的改变.
git checkout filename
- git命令对各个区的影响
git add. 将工作区的文件添加到缓存区域
git commit 是将缓存区的内容增加到本地仓库
git checkout --file 是将工作区的内容丢弃
git reset --hard HEAD^ 是将当前的index 直接指向上一个版本, 并且将 暂存区,仓库,工作区的内容变动全部删除.
git reset --mixed HEAD^ 或者git reset HEAD^ 将缓存区,本地仓库的变动删除, 但是保留工作区的文件的变动.
git reset --soft HEAD^ 表示本地仓库的 commit的内容丢弃,保留本地和缓存区的变动.
不想提交某些文件到仓库
在项目中,有些文件不需要上传, 比如java的字节码文件 , log日志文件是不需要上传到git服务器器的,那么这个时候,就可以在项目的根目录下面创建.gitignore 文件, 把不需要上传的文件忽略掉即可.
.在使用Git管理代码的过程中,可以修改.gitignore文件中的标示的方法来忽略开发者想忽略掉的文件或目录,如果没有.gitignore文件,可以自己手工创建。在.gitignore文件中的每一行保存一个匹配的规则例如:
# 此为注释 – 将被 Git 忽略
*.a # 忽略所有 .a 结尾的文件
!lib.a # 但 lib.a 除外
/TODO # 仅仅忽略项目根目录下的 TODO 文件,不包括 subdir/TODO
build/ # 忽略 build/ 目录下的所有文件
doc/*.txt # 会忽略 doc/notes.txt 但不包括 doc/server/arch.txt
在填写忽略文件的过程中,我发现.gitignore中已经标明忽略的文件目录下的文件,当我想git push的时候还会出现在push的目录中,原因是因为git忽略目录中,新建的文件在git中会有缓存,如果某些文件已经被纳入了版本管理中,就算是在.gitignore中已经声明了忽略路径也是不起作用的,这时候我们就应该先把本地缓存删除,然后再进行git push,这样就不会出现忽略的文件了。git清除本地缓存命令如下:
git rm -r --cached .
git add .
git commit -m 'update .gitignore'
还有一种情况, 就是发现某个文件,已经写到了.gitignore中 , 但是已经上传到了,git服务器上面.
那么这个文件, 无论你怎么修改,每次上传都是会被忽略掉的.但是呢, 项目中又存在这种文件, 这种文件一般是本地开发的配置文件. 如果你重新让.gitignore
文件生效, 那么先前忽略的文件会被删除掉, 也就是说, 以前文件存在,.gitignore
填写的配置不生效. 但是现在你删除了缓存,.gitignore
文件生效了, 那么会导致原来的文件丢失. 这个是我亲身经历过的. 一定要注意,这种问题发生, 导致丢失不必要的配置文件.
git checkout origin/2.1.0-llw 拉趣远程分支
git checkout --track origin/branch_name 建立关联
git branch --set-upstream-to remotes/origin/news
git branch --set-upstream-to=origin/rzzm_202011208 rzzm_202011208
参考: