零散的git记录,汇总
摘要:
版本回退
常用形式: git reset HEAD^ --hard
一般形式: git reset [commit_Id] --hard
Tips : HEAD^^ HEAD^^^ ...HEAD~100(分别表示指向的的是当前版本前前、前前前...版本。下文关于回退的表示采用一般形式
如果未添加--hard,表示撤回到暂存区,工作区不回退(关于 --hard 参数的解释可以参考文件回退)
commit_Id 可以通过 git log | git reflog | git log --graph --pretty=oneline --abbrev-commit 获取
版本回退的问题
推送到远程仓库的情况下,假设未回退之前为
a->b->c
进行回退后
a->b
想修改后,
a->b->d
这时push remote时会失败,因为本地库是a->b->d 远程库 a->b->c 相对于remote库来说,d之后的commit_Id对不上了(猜测)
两个解决方案
1. push 时强制远程仓库做出改变 后面加参数 --force 不推荐
2. 反向操作 使用git revert [commit_Id] 即 a->b->c->e->d =>实现a->b->d (e为b 的快照,系上一个扣)
文件的回退
如果项目文件没有添加到暂存区:
git checkout -- [filename]将回退的文件在工作区的修改全部撤销
(其实质是由暂存区覆盖,所以会有下文提到的会回到git commit 或者 git add时的状态)
如果已经 commit 本地版本库 可参考之前的 版本回退的问题 (push到远程仓库,就很残酷了)
总之git checkout -- [filename]是让文件回到最近一次 git commit 或 git add 时的状态
经过上述操作之后,工作区回退的文件与暂存区或者版本库的文件是相同的(暂存区为空)
有没有全体文件,回退呢;-(
有的,git reset HEAD --hard <解释可以看下一个情景的分析>
如果项目文件已经添加到暂存区:
想要回退,这里的回退可以描述为: 撤销对已经添加到暂存区的项目文件的修改
git reset HEAD (这里未添加 --hard,这样只是丢弃添加到到暂存区的修改)
经过上述操作之后,问题描述转为上一个问题描述:撤销对还没有添加到暂存区的项目文件的修改
针对已经添加到暂存区的文件能不能一步到位,不再回到情景一呢?
使用 git reset [commitId] --hard 这时 --hard参数显得尤为关键
当使用 git reset [commitId] 进行版本回退时(reset的字面意义较为贴切),
可认为是由[commitId]所代表的的版本库直接覆盖到当前版本库(确切的是HEAD指向),
同时清空暂存区,加上 --hard 参数 可以将reset的影响波及到工作区,
就可达到"一步到位"的目的。
类似于用git checkout -- [filename] 遍历所有修改过的文件,全部撤销修改
如果项目文件已经提交到本地:
git reset HEAD^ 可以回退改动到本地工作区,但是对应的CommitId会被丢弃,可以通过 git revert <最近一次的CommitId> -n 达到同样的目的
Tips: 由此可见 --hard 参数是 git checkout -- [filename]的"批处理"加强版,
但是不能由提交到暂存区的文件还原,因为它已经被清空
git diff
git diff #是工作区(work dict)和暂存区(stage)的比较
git diff -- cached #是暂存区(stage)和分支(master)的比较
紧急处理bug
储存现场
git stash //暂时冰冻当前正在进行的工作
git checkout master //切换到bug分支,假定主分支上出现bug
git checkout -b issue_102
修复bug
...
.. add ..|..commit ..
git checkout master
git merge --no-ff -m "merge bug fix issue_102" issue_102
// 合并分支时,默认采用Fast-forward模式,由于快速合并只是HEAD指向的改变,
// 所以当删除修改后的bug分支时,bug分支的commitId已经不可见
// <虽然可以通过git reflog查看所有的炒作记录操作,找到commitId>
所以这里加上 --no-ff 禁用fast-forward.这时当删除bug分支相关的"痕迹",也能一目了然,毕竟有个"三脚架"
git branch -d issue_102
// bug 修复完毕切回 dev 继续 coding
git checkout dev
恢复现场
git stash list
git stash apply stash@{0}
// 使用 apply 恢复现场时,stash内容还保存着,可以通过 git stash drop stash@{?}删除相关stash,
// 用git stash pop 默认恢复stash@{0}
当然可以通过 git stash pop stash@{?}在恢复现场的同时,删除drop stash@{?},实现"一步到位"
当用git stash 多次冰冻现场时,最新的stash 在列表中始终是stash@{0} 其内部是采用"栈"存储的,其中stash@{0}为栈顶元素
拓展
不难想象可以用git stash 配合 git stash drop stash@{?}(即"储藏"之后不进行"还原"操作)来达到在上面文件回退部分执行的操作一样的效果
思考
可以使用git add 和 git checkout -- [filename] 实现git stash的功能吗
Tips:只有 git checkout --[filename]可以从暂存区还原文件(暂存区不为空时),同时也只有它能使单个文件得到还原。所以针对文件的回退, 我们有不少选择(--hard 和 git stash ,git stash drop)
Tips: 关于思考的问题结论是不行的,如果你的想切换分支但是有未提交到版本库的文件,git 是不会让你切换的,在暂存区也不行(更准确的讲是当要提交的文件不是新创建的文件,而是已经提交过有更新的文件,会阻止提交)
分支的管理
关于远程分支的克隆,git clone -b {远程分支名} 可在本地创建一个与远程分支同名本地分支的git仓库
推送本地分支
git push origin localBranch:RemoteBranch
Tips : 使用本地的对应分支来更新对应的远程分支。 如果省略远程分支名,则表示将本地分支推送与之存在”追踪关系”的远程分支(通常两者同名),如果该远程分支不存在,则会被新建
git push 表示将所在分支推送到远程对应分支上(如果仓库和多个主机相连,要通过git push -u 指定默认推送主机)
注意如果使用git push origin :master 未加上本地分支名(此时默认要推送的到远程的分支为空分支) 将会删除远程仓库下的master,等同于git push origin --delete master
git checkout -b 本地分支名 origin/远程分支名
将远程git仓库里的指定分支拉取到本地(本地不存在的分支)
拉取远程分支
git pull origin Remote:Local
git pull origin master:my_test
省略本地分支,默认与当前所在分支合并
Notice:前后位置
推送 本地——>远程
拉取 远程——>本地
分支的合并
git merge [要合并到当前分支的分支]
//默认执行ff模式(fast-forward)
git merge --no-ff -m "merge report.." [待合并分支]
分支的关联
git remote add origin git@github.com/HUkiah/XXX.git
进行push操作时,会fail,需要进行pull ,如果远程仓库存在Readme.md文件
拉取时需添加 --rebase参数,类git pull --rebase origin master,如此可保障push success
上面的rebase参数和merge实现相同的功能,区别在于使用merge log会保留各自的commit历史
rebase log会丢弃被合并分支的commit history
(上述问题,未用merge试验)
变基操作的实质是丢弃一些现有的提交,然后相应地新建一些内容一样但实际上不同的提交,等同于先 git fetch,再 git rebase teamone/master
如下图
想要c8-c9的提交 合并到master分支,过滤c3的操作时,可以尝试rebase
取消关联
git remote remove origin

维护扩展:
修改分支名 git branch -m [old] [new]
配置ssh-key
ssh-keygen -t rsa -C "your_email@example.com"
期望对repo中的文件不进行追踪 需要设置.gitignore文件
对于已经添加的追踪则需要 清空缓存区的文件,方能解决.gitignore的问题
删除本地分支
git branch -d < branchName >
2020年05月21日17时40分:
git clone --depth=1 git://someserver/somerepo
depth用于指定克隆深度,为1即表示只克隆最近一次commit.
2021年03月15日10时49分:
Git合并特定到Commits到当前分支
- 合并单个commit
git cherry-pick 2541354 - 合并一系列commits
假如要合并feature分支的2~3分支
git checkout -b newbranch 3
然后rebase这个新分支的commit到targetBranch
git rebase --onto target 2^
(上述rebase的表述,先忽视吧 我还不理解)
Git合并特定commits 到另一个分支
解决冲突
多人协作的情况下,分支合并时经常会出现几个热点文件的冲突。
在feature分支 我们往往只想处理和冲突相关的文件,不想merge整合有冲突的分支到feature分支。使用git-cherry pick能够实现merge单次提交,但是还是无法实现我们只处理和冲突相关文件的目的。
具体操作如下
git cherry-pick --no-commit
git reset HEAD [filepath] 或 (git reset HEAD 配合 add和checkout)
对于pick的newfile可以使用git clean -f移除
2021年04月22日10时51分:
一类项目归到统一的仓库管理的场景
需要检出一个空白分支
git checkout --orphan
Create a new orphan branch, named <new_branch>, started from
and switch to it. The first commit made on the new branch will have no parents and it will be the root of a new history totally disconnected from all the other branchs and commits.
添加--orphan参数就检出了一个commit log没有联系的branch,但是还会保留被检分支的文件,可以手动删除这些多有的文件
空的更彻底
参考链接:在GIT中创建一个空分支
2021年06月29日19时14分:
撤销工作区域某文件夹下的更改,先找到要还原版本的commitId,通过git checkout [commitId ] [relative path] 即可
2022年01月18日
新增之前已经在repo中的文件忽略规则到gitignore文件 无效的问题
git rm -r --cached .
git add .
git commit -m ""
2022年10月26日
git rebase的操作可以参考这个博客的说明 git rebase 用法详解与工作原理
2023年10月9日
添加版本回退的内容 => 如果项目文件已经提交到本地:

浙公网安备 33010602011771号