stash
git stash
: 暂存没有add的修改git stash list
: 查看已经暂存的git stash apply
: 应用暂存的修改到当前分支
工作流
- Git 工作流程 - 阮一峰的网络日志
- Git flow
- Github flow
checkout & merge
1) git clone
检出代码:
- 显示remote:(origin是远程库的名字)
git remote -v
查看可以抓取和推送的origin的地址git remote show origin
, 比上面的更详细, 可以看到git pull/push到的默认是哪个分支.
2) git checkout -b issue3 origin/master
, 从远端的master分支创建一个自己的分支issue3
- 创建新分支并立即切换到新分支:
git checkout -b [name]
- 如果这时候
git pull
从服务器拉新代码, 会失败并提示服务端的分支没有和新分支对应:git branch --set-upstream-to=origin/master [分支名]
- 如果这时候
3) 合并源分支(issue3) 到远程目标分支(master):
git pull --rebase origin master
// 在issue3分支pull最新的master代码git checkout master
// 切换到目标分支git merge --no-ff issue3
//--no-ff
禁用 Fast forward模式, 这样删除分支后也不会丢掉分支信息git push origin master
- 如果merge时出现冲突:
- 修改冲突文件, 然后重新
git add confilct_file
(重新staged), 将把它们标记为已解决状态(译注:实际上就是来一次快照保存到暂存区域)。因为一旦暂存,就表示冲突已经解决。 - 然后不要忘了:
git commit -m "conflict fixed"
- 解决完冲突, push上去
git push origin master
- 修改冲突文件, 然后重新
4) 合并完成后, 删除开发分支:
git branch -d <branch_name>
# 如果这个分支没有被merge,git会提示git branch -D <branch_name>
# -D就是强行删除git push origin --delete <branch_name>
如需要删除远程分支:
rebase
➤ 用rebase 合并commit记录:
- 使用
git rebase
有两种:git rebase -i HEAD~4
// 从HEAD开始往前4次commit合并成一个git rebase -i star_commit end_commit
// 前开后闭区间, 合并范围不包括start_commit
, 如果不写end_commit
则默认是HEAD
进入vi模式(for example: 第一个commit标记为pick, 后面几个commit标记为squash, 这样会把后几个commit合并到第一个), wq保存退出, git会合并commit历史
git log --graph --pretty=oneline --abbrev-commit
查看结果- 如果发生冲突, 修改后
git add .
, 然后git rebase --continue
.. - rebase完,
git log
查看一下合并结果, 然后推到远端分支git push -f origin <branch>
➤ merge之前使用git rebase
:
- 切换到私有分支, 然后
git rebase origin master
// 与pull --rebase master
的区别? - 如果有有冲突:
- 修改冲突的文件, 然后
git add file
- 修改完后, 不commit而是
git rebase --continue
- 撤销此次Merge :
git rebase --skip
(可能多次)
- 修改冲突的文件, 然后
git checkout master
git merge issue3
➤ git rebase master
发生了什么?
- 把issue3分支每个commit取消掉, 并把这些commit保存到.git/rebase下作为临时patch)
- 把当前分支(issue3)更新到最新的master
- 把步骤1的patch应用到当前分支
- ps: 解决冲突后继续
git rebase --continue
// 继续应用剩下的patch
cherry-pick
git cherry-pick <commit_hash>
// 把这次commit应用到 当前分支, ps支持多个提交(空格分隔)git cherry-pick <branch>
// 把这个分支所有commit应用到 当前分支- 如果 cherry-pick 出现冲突, 修改完冲突需要再执行:
git add confilct_file
git commit -m "conflict fix"
撤销和回滚
- 修改了文件, 但还没有git add: 输入
git status
, 会提示用git checkout -- file
丢弃工作区, 文件回到服务器状态; - 修改并add了README.md, 还没有commit: 输入
git status
, 提示usegit reset HEAD filename
to unstage; - 如果已commit/已merge:
git log -p -n 3
查看最近3次历史, 记录下commit的哈希值, 然后执行git reset --hard commit_hashid
如果已push:
git reflog
查看 commit_hashidgit reset --hard commit_hashid
git push -f
// 把本地的修改强制推送到远程分支上强制推送到mster可能会报错,意思是没有权限之类的错误,报错如下。
remote: GitLab: You don't have permission
To git@10.255.223.213:code-ddreader/media-hapi.git
! [remote rejected] master (pre-receive hook declined)是因为master分支一般会成为保护分支,所以我们首先要去除master为保护分支,才可以强推。
有用的alias设置
git config --global alias.co checkout |
以及: git config --global core.autocrlf false
使用LR而不是Win系统的CRLF