转自: https://github.com/kaiye/kaiye.github.com/issues/7php
在掌握了基础的 Git 使用 以后,可能会遇到一些问题。如下是猫哥筛选总结的部分常见问题,分享给各位朋友,掌握了这些问题的中的要点以后,git 进阶也就完成了,它包含如下部分:html
git remote add origin <git仓库地址>
# 如下三种方式都可 git config get --remote.origin.url git remote -v git remote show origin
git remote rm origin
接下来以添加 github ssh keys 为例,请注意替换 github 文件名。git
注:若是对密钥机制不熟悉,建议不要指定 -f 参数,直接使用默认的 id_rsa 文件名。github
# 运行如下命令,一直回车,文件名可随意指定 ssh-keygen -t rsa -b 4096 -C "kaiye@macbook" -f ~/.ssh/github # 若是不是默认密钥 id_rsa ,则须要如下命令注册密钥文件,-K 参数将密钥存入 Mac Keychain ssh-add -K ~/.ssh/github # 将 pub 公钥的内容粘贴到线上网站的后台 cat ~/.ssh/github.pub # 测试 git ssh 是否链接成功 ssh -T git@github.com
修改包含四种状况,需单独区分。服务器
此类文件的状态为 Untracked files
,撤销方法以下:app
git clean -fd .
其中,.
表示当前目录及全部子目录中的文件,也能够直接指定对应的文件路径,如下其余状况相似。ssh
此类文件的状态为 Changes not staged for commit
,撤销方法:编辑器
git checkout .
此类文件的状态为 Changes to be committed
,撤销方法:svn
git reset .
执行以后文件将会回到以上的 1 或者 2 状态,可继续按以上步骤执行撤销,若 git reset 同时加上 --hard
参数,将会把修改过的文件也还原成版本库中的版本。工具
每次提交都会生成一个 hash 版本号,经过如下命令可查阅版本号并将其回滚:
git log git reset <版本号>
若是须要「回滚至上一次提交」,可直接使用如下命令:
git reset head~1
执行以后,再按照 1 或者 2 状态进行处理便可,若是回滚以后的代码同时须要提交至 origin 仓库(即回滚 origin 线上仓库的代码),须要使用 -f
强制提交参数,且当前用户须要具有「强制提交的权限」。
若是是以上的状况 1 或者 2,只能歇屁了,由于修改没入过版本库,没法回滚。
若是是状况 4,回滚以后经过 git log 将看不到回滚以前的版本号,但可经过 git reflog
命令(全部使用过的版本号)找到回滚以前的版本号,而后 git reset <版本号>
。
两个分支进行合并时(一般是 git pull 时),可能会遇到冲突,同时被修改的文件会进入 Unmerged
状态,须要解决冲突。
大部分时候,「最快解决冲突」的办法是:使用当前 HEAD 的版本(ours),或使用合并进来的分支版本(theirs)。
# 使用当前分支 HEAD 版本,一般是冲突源文件的 <<<<<<< 标记部分,======= 的上方 git checkout --ours <文件名> # 使用合并分支版本,一般是源冲突文件的 >>>>>>> 标记部分 git checkout --theirs <文件名> # 标记为解决状态加入暂存区 git add <文件名>
用编辑器打开冲突的源文件进行修改,可能会发生遗留,且体验很差,一般须要借助 git mergetool 命令。
在 Mac 系统下,运行 git mergetool <文件名>
能够开启配置的第三方工具进行 merge,默认的是 FileMerge 应用程序,还能够配置成 Meld 或 kdiff3,体验更佳。
有三个好的习惯,能够减小代码的冲突:
git pull
一下;若是你的项目周期比较长,还应该养成「按期 rebase 的习惯」,git pull --rebase
可让分支的代码和 origin 仓库的代码保持兼容,同时还不会破坏线上代码的可靠性。
它的大概原理是,先将 origin 仓库的代码按 origin 的时间流在本地分支中提交,再将本地分支的修改记录追加到 origin 分支上。若是发生冲突,则能够即时的发现问题并解决,不然到项目上线时再解决冲突,可能会发生额外的风险。
rebase 大概的操做步骤以下:
# 将当前分支的版本追加到从远程 pull 回来的节点以后 git pull --rebase # 若发生冲突,则按以上其余方法进行解决,解决后继续 git rebase --continue # 直到全部冲突得以解决,待项目最后上线前再执行 git push origin # 若屡次提交修改了同一文件,可能须要直接跳事后续提交,按提示操做便可 git rebase --skip
有些修改没有彻底完成以前,可能不须要提交到版本库,圡方法是将修改的文件 copy 到 git 仓库以外的目录临时存放,pull / merge 操做完成以后,再 copy 回来。
这样的作法一个是效率不高,另一个可能会遗漏潜在的冲突。此类需求最好是经过 git stash
命令来完成,它能够将当前工做状态(WIP,work in progress)临时存放在 stash 队列中,待操做完成后再从 stash 队列中从新应用这些修改。
如下是 git stash 经常使用命令:
# 查看 stash 队列中已暂存了多少 WIP git stash list # 恢复上一次的 WIP 状态,并从队列中移除 git stash pop # 添加当前 WIP,注意:未提交到版本库的文件会自动忽略,只要不运行 git clean -fd . 就不会丢失 git stash # 恢复指定编号的 WIP,同时从队列中移除 git stash pop stash@{num} # 恢复指定编号的 WIP,但不从队列中移除 git stash apply stash@{num}
默认的 git log 会显示较全的信息,且不包含文件列表。使用 --name-status
能够看到修改的文件列表,使用 --oneline
能够将参数简化成一行。
git log --name-status --oneline
每次手动加上参数很麻烦,能够经过自定义快捷命令的方式来简化操做:
git config --global alias.ls 'log --name-status --oneline --graph'
运行以上配置后,可经过 git ls
命令来实现「自定义 git log」效果,经过该方法也能够建立 git st
、git ci
等一系列命令,以便沿用 svn 命令行习惯。
git config --global alias.st 'status --porcelain'
更多 git log 参数,可经过 git help log
查看手册。
若是是看上一次提交的版本日志,直接运行 git show
便可。
例如,在执行 git submodule update 时有如下错误信息:
fatal: reference is not a tree: f869da471c5d8a185cd110bbe4842d6757b002f5 Unable to checkout 'f869da471c5d8a185cd110bbe4842d6757b002f5' in submodule path 'source/i18n-php-server'
在此例中,发生以上错误是由于 i18n-php-server 子仓库在某电脑 A 的「本地」commit 了新的版本 「f869da471c5d8a185cd110bbe4842d6757b002f5」,且该次 commit 未 push origin。但其父级仓库 i18n-www 中引用了该子仓库的版本号,且将引用记录 push origin,致使其余客户机没法 update 。
解决方法,在电脑 A 上将 i18n-php-server 版本库 push origin 后,在其余客户机上执行 git submodule update 。或者用以上提到的 git reset 方法,将子仓库的引用版本号还原成 origin 上存在的最新版本号。
设置本地分支与远程分支保持同步,在第一次 git push 的时候带上 -u
参数便可
git push origin master -u
支持中文目录与文件名的显示(git 默认将非 ASCII 编码的目录与文件名以八进制编码展现)
git config core.quotepath off
经常使用的打 tag 操做,更多请查看《Git 基础 - 打标签》
# 列出全部本地 tag git tag # 本地新增一个 tag,推送至 origin 服务器 git tag -a v1.0.0 -m 'tag description' git push origin v1.0.0 # 删除本地与 origin tag git tag -d v1.0.0 git push origin --delete v1.0.0
使用 git GUI 客户端(如,SoureTree、Github Desktop)能极大的提高分支管理效率。分支合并操做一般只有两种状况:从 origin merge 到本地,使用 git pull
便可;从另一个本地分支 merge 到当前分支,使用 git merge <分支名>
,如下是经常使用命令:
# 新建分支 branch1,并切换过去 git checkout -b branch1 # 查看全部本地与远程分支 git branch -a # 修改完成后,切换回 master 分支,将 branch1 分支合并进来 git checkout master git merge branch1 # 删除已完成合并的分支 branch1 git branch -d branch1