git常用操作
将远程仓库里的指定分支拉取到本地(本地不存在的分支)
git checkout -b 本地分支名 origin/远程分支名
如果出现提示:
fatal: Cannot update paths and switch to branch 'dev2' at the same time.
Did you intend to checkout 'origin/dev2' which can not be resolved as commit?
表示拉取不成功。我们需要先执行
git fetch
然后再执行
git checkout -b 本地分支名 origin/远程分支名
本地检出一个新的分支并推送到仓库
创建新分支, 创建后会自动切换到新分支
git checkout -b 新分支名
将新分支推送至远程仓库(原仓库中没有该分支), 注意确保当前所在的分支是新分支
git push --set-upstream origin 分支名
cherry-pick用法
cherry_pick
可以将A分支的某些指定的提交(commit)应用于B分支
基本用法
先切换到B分支
git checkout -b B
再执行cherry_pick
命令, 将指定的提交commitHash
,应用于当前分支
git cherry-pick <commitHash>
如果git cherry-pick
命令的参数是分支名,表示将该分支的最近一次提交,转移到当前分支。
git cherry-pick feature
转移多个提交
将 x和 y这两个提交应用到当前分支
git cherry-pick <HashX> <HashY>
如果想要转移一系列的连续提交,即把X(不包括X)和Y(包括Y)两者之间(即左开右闭区间(X:Y])的所有提交都应用到当前分支, 可以使用下面的简便语法.
git cherry-pick <HashX>..<HashY>
注意,使用上面的命令,提交 X 将不会包含在 Cherry pick 中。如果要包含提交 X,可以使用下面的语法。
git cherry-pick X^..Y
代码冲突
如果操作过程中发生代码冲突,Cherry pick 会停下来,让用户决定如何继续操作。
(1)--continue
用户解决代码冲突后,第一步将修改的文件重新加入暂存区(git add .
),第二步使用下面的命令,让 Cherry pick 过程继续执行。
$ git cherry-pick --continue
(2)--abort
发生代码冲突后,放弃合并,回到操作前的样子。
(3)--quit
发生代码冲突后,退出 Cherry pick,但是不回到操作前的样子。
rebase用法
合并多个commit为一个完整commit
git rebase -i HashStart HashEnd
- -i 意思是
--interactive
, 表示会弹出交互式的界面让用户编辑完成合并操作 - start和end是一个左开右闭的区间(start, end], 即合并时不包括start, 会包括end. 如果不指定end, 则默认为当前分支head所指向的commit
如有A->B->C->D四个提交, 现在想把B->C->D三个提交合并成一个提交, 可以使用rebase命令
git rebase -i A D
然后我们会看到如下界面:
上面未被注释的部分列出的是我们本次rebase操作包含的所有提交
下面注释部分是git为我们提供的命令说明。每一个commit id 前面的pick
表示指令类型,git 为我们提供了以下几个命令:
pick:保留该commit(缩写:p)
reword:保留该commit,但我需要修改该commit的注释(缩写:r)
edit:保留该commit, 但我要停下来修改该提交(不仅仅修改注释)(缩写:e)
squash:将该commit和前一个commit合并(缩写:s)
fixup:将该commit和前一个commit合并,但我不要保留该提交的注释信息(缩写:f)
exec:执行shell命令(缩写:x)
drop:我要丢弃该commit(缩写:d)
我们需要在b提交前使用pick, 在c和d提交前使用squash(缩写:s), 将c和d的提交合并到前面的b上
然后是注释修改界面:
编辑完保存即可完成commit的合并了:
回退版本
先查看git提交日志, 记住要回退至哪个版本的commit_id
git log
回退至制定版本号
git reset --hard commit_id
快捷命令, 回退至上个版本
git reset --hard HEAD^ # 上个版本
git reset --hard HEAD^^ # 上上个版本
将本地重置为和远程一致(远程强制覆盖本地)
git fetch origin # 从 origin 下载对象和引用
git reset --hard origin/master # 将当前的 HEAD 重置为远程分支上的那个。请注意,这将删除所有本地更改。
修改最近一次提交的message
git commit --amend
删除未跟踪文件
# 删除 untracked files
git clean -f
# 连 untracked 的目录也一起删掉
git clean -fd
# 连 gitignore 的untrack 文件/目录也一起删掉 (慎用,一般这个是用来删掉编译出来的 .o之类的文件用的)
git clean -xfd
# 在用上述 git clean 前,墙裂建议加上 -n 参数来先看看会删掉哪些文件,防止重要文件被误删
git clean -nxfd
git clean -nf
git clean -nfd
删除分支
git branch -d tt
在oh my zhs中git慢/卡顿
原因是因为 oh-my-zsh 要获取 git 更新信息
解决办法:
设置 oh-my-zsh 不读取文件变化信息(在 git 项目目录执行下列命令)
git config --add oh-my-zsh.hide-dirty 1
如果你还觉得慢,可以再设置 oh-my-zsh 不读取任何 git 信息
git config --add oh-my-zsh.hide-status 1
如果想恢复,设置成0就好
设置代理
全局代理
# 设置代理
git config --global http.proxy "http://proxy_url"
git config --global https.proxy "https://proxy_url"
# 取消设置
git config --global --unset http.proxy
git config --global --unset https.proxy
单独代理
# clone时设置代理
git clone --config http.proxy="http://proxy_url" https://github.com/chaitin/xray.git
本地添加关联的远程地址
一般在执行git clone
后, 会自动给本地路径添加远程信息, 通过git config -l
命令查看
$ git config -l
# 默认的远程名为origin
remote.origin.url=https://github.com/chaitin/xray.git
# 默认master对应的远程为origin
branch.master.remote=origin
也可以给这个本地仓库添加多个远程地址, 使用git remote add 自定义远程名 远程地址
命令添加, 如:
git remote add origin_gitlab git@git.dev.sh.ctripcorp.com:infosecau/xray.git
添加后, 重新查看git config
$ git config -l
# 默认的远程名为origin
remote.origin.url=https://github.com/chaitin/xray.git
# 默认master对应的远程为origin
branch.master.remote=origin
# 新增的远程, 名为origin_gitlab
remote.origin_gitlab.url=git@git.dev.sh.ctripcorp.com:infosecau/xray.git
这样就能够实现从一个远程仓库(如github)拉取代码至本地, 再push到另一个远程仓库(如gitlab), 通过手动的方式实现两个仓库的代码同步.
当然也可以通过自动化的方式实现两个仓库代码同步, 比如在gitlab的仓库设置镜像配置(Settings->Repository->Mirroring repositories), 但如果gitlab服务只部署在公司内网, 无法访问github, 那么就可以通过上述的手动方式实现同步(前提是有git代理能访问github)
GIT PUSH 时如何避免出现 "MERGE BRANCH 'MASTER' OF ..."
当本地分支落后于 remote 远程分支时
- 如果本地分支没有其他 commit 的,直接从 remote 进行 pull 操作,默认会采用
fast-forward
模式,这种模式下,并不会产生合并节点,也就是说不会产生多余的那条 log 信息 - 如果本地先 commit 过后再去 pull,那么此时,remote 分支和本地会分支会出现分叉,这个时候使用 pull 操作拉取更新时,就会进行分支合并,产生合并节点和 log 信息。
使用 git pull --rebase
可以避免。如果拉取不产生冲突,会直接 rebase,不会产生分支合并操作,如果有冲突则需要手动 fix 后,自行合并。