Git环境配置
一、 全局配置
1. 配置文件
git全局配置文件.gitconfig
默认在当前系统用户文件夹下,window可运行%USERPROFILE%
查找,Mac系统在cd ~查找。
具体配置可参考如下,其中:
【user】: 用户提交时显示在log里的信息
【alias】: 常用git命令简写
【core】: window系统和类linux系统回车键转换
【push】: 默认对应远端(当本地分支名与远程分支名不一致有用)
[user]
name = hoby
email = hoby@github.com
[alias]
st = status
co = checkout
br = branch
ci = commit
pl = pull --rebase
ps = push
mg = merge --no-ff
lg = log --color --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset' --abbrev-commit
[core]
autocrlf = input
ignorecase = false
[push]
default = upstream
若要使用git mergetool
功能,再增加配置(cmd处可修改成本地文件比较工具如beyond compare):
[merge]
tool = sourcetree
[diff]
tool = sourcetree
[difftool "sourcetree"]
cmd = 'C:/Program Files/TortoiseGit/bin/TortoiseGitMerge.exe' \"$LOCAL\" \"$REMOTE\"
[mergetool "sourcetree"]
cmd = 'C:/Program Files/TortoiseGit/bin/TortoiseGitMerge.exe' -base:\"$BASE\" -mine:\"$LOCAL\" -theirs:\"$REMOTE\" -merged:\"$MERGED\"
trustExitCode = true
2. 命令修改
如果不加--global 修改的是当前项目git配置。
$ git config --global --list # 查看全局配置
$ git config --local --list # 查看本项目配置
$ git config --global user.name hoby # 修改提交名
$ git config --global alias.br branch # 修改简写
$ git config --global core.ignorecase false # 关闭忽略大小写
$ git config --unset alias.name # 默认删除当前项目配置,加--global删除全局
二、 Git密钥配置
1. 单项目自动化clone
如果想快速简单的clone一个git项目,在拉取时直接带上用户名+密码,此方法在服务器自动化构建时经常用到,具体实现如下:
$ git clone http(s)://username:passwd@githbub.com/hoby/xxx.git
需注意的是:此处username一般为用户名非整个邮箱地址,比如hoby@qq.com的用户,只需要用hoby即可,若一定需要完整邮箱地址可将邮箱中的@符号使用%40替换
2. 以SSH方式全局配置密钥
1.)检查SSH Key存在
如果存在id_rsa.pub 或 id_dsa.pub 文件,跳过此步。
$ cd ~/.ssh # 查看用户根目录下.ssh文件夹
$ ls
2.)创建SSH Key
创建ssh key时会提示自定名称和push时的密码(不是git登录密码),一般推荐略过,直接三个回车,如果创建成功会出来一个有图案的小框框。
# 此email可任意,不一定要gitLab登录邮箱
$ ssh-keygen -t rsa -C "your_email@example.com"
3.)查看SSH Key
copy公钥内容到gitLab里,添加进去。
$ cat ~/.ssh/id_rsa.pub
4.)测试SSH Key
$ ssh -T "git@xxx.xxx.com"
5.)配置多个网站ssh密钥
在生成每个网站ssh-key时,自定义名称不要一样,然后在~/.ssh目录下新建一个config文件,然后配置多个网站的ssh信息,内容如下:
# gitLab
Host dev.gitLab.com
HostName dev.gitLab.com
PreferredAuthentications publickey
IdentityFile ~/.ssh/id_rsa
# phabricator
Host 192.168.1.5
HostName 192.168.1.5
Port 22
PreferredAuthentications publickey
IdentityFile ~/.ssh/phabricator
3. HTTP(S)方式全局配置密码
http(s)创建的项目,操作时总是提示用户名和密码,不胜其烦,以下方案可以让Git永远记住用户名与密码:
1.)添加HOME变量
在Windows用户变量中添加一个HOME环境变量,值为%USERPROFILE%
,如下图:
2.)创建_netrc文件
在"开始>运行"中打开%Home%
,新建一个名为_netrc
的文件,输入Git服务器名、用户名、密码保存,可放多个不同登录信息的Git项目,中间空一行即可,具体内容如下:
machine dev.github.com
login hoby
password 123456
4. HTTP(S)方式的Git凭证存储
有时你在winodws/Mac下以http(s)方式clone项目时会发现,第一次输入的用户名和密码会被系统记住,后面不用再输入。这些是git通过credential helper(凭证小助手)帮你实现的, helper的类型有很多,具体可通过如下命令查看当前你的类型:
$ git config --list | grep credential
a.) Mac系统:
git默认提供osxkeychain辅助程序来管理你的密码,具体可以通过Mac系统菜单页面“其他->钥匙串访问”功能查看b.) Windows下凭证存储类型有四种:
git-credential-winstore、git-credential-manager(如果安装了Git GUI),git-credential-store(在.gitconfig配置store路径)和git-credential-cache(缓存在内存),例如,若Windows安装Git GUI后,通过上面的命令查看,默认会输出:
credential.helper=manager
windows下git凭证存储位置:控制面板->用户账户->管理windows凭据,可去查看或修改
Git常用命令
一、仓库管理
1. 初始化
初始化后,目录下会生成.git
隐藏文件夹,图标显示git可控,.git
目录下有一个hooks,里面可以对预提交信息做一些规范和限制。
$ git init
2. 添加/修改仓库地址
a.) 添加关联地址:
$ git remote add origin http://dev.github.com:9800/root/front.git
b.) 修改关联地址:
$ git remote set-url origin http://dev.github.com:9800/root/front.git
c.) 添加多个远程仓库:
添加多个origin,本地可同时push到多个远程仓库
$ git remote set-url --add origin http://dev.github.com:9800/root/front.git
d.) 切换http(s)/ssh方式:
$ git remote rm origin
$ git remote add origin "git远程地址"
$ git push origin
3. 查看当前仓库地址
$ git remote -v
4. 创建本地仓库
$ git clone http://dev.github.com:9800/root/front.git
会在当前目录下自动生成front的仓库目录,如果自定义文件夹名,后面空格后加上名称
二、分支管理
1. 查看分支
$ git br # 查看本地
$ git br -r # 查看远端
$ git br -a # 查看所有
2. 查看分支状态(推荐)
可全面查看本地分支状态,远端对应关系,落后/优先多少,最后一次提交信息及hash值
$ git br -vv
3. 创建分支
a.) 创建本地分支:
本地分支名可不与远程一致,简单一点,方便Tab键补全,只要.gitconfig
里的[push]
项设置default = upstream
即可,不然提交时,会提示本地与远程不一致
$ git br <branch> <remote-branch> # 创建分支,并关联远端
# 或:
$ git co -b <branch> <remote-branch> # 创建分支并立即切换过去
b.) 创建远程分支:(本地分支推送到远端)
$ git push origin -u <branch> # -u:创建远程分支并关联
如果想自定义本地分支名(与远端名称不一致),可如下:
$ git push origin -u <branch>:<remote-branch>
4. 切换分支
$ git co <branch>
# 切换到游离分支(不在任何分支)
$ git fetch
$ git co FETCH_HEAD
5. 合并分支
a.) 合并本地分支:
$ git merge <branch> --no-ff # --no-ff:关闭Fast-Foward合并,这样可以生成merge提交,保留分支合并信息
会出来vim编辑窗口(可修改提交信息),不修改则按shift + : 再输入wq(保存退出)后回车即可。
b.) 合并远端本地(不用先checkout到本地):
$ git fetch # 先更新远程仓库所有分支上最新commit-id到本地
$ git merge origin/<branch> --no-ff # 再从远端merge,无需先拉取到本地
c.) 取消合并:
$ git merge --abort
d.) 合并冲突处理:
$ git mergetool # 如果在~/.gitconfig下正确配置了比较工具,会依次弹出比较窗口,处理后保存
$ git clean -nfd # 查看不在版本库中合并文件,以.org结尾
$ git clean -fd # 确认无误后,移除这个.org临时文件
$ git add -A
$ git merge --continue # 继续完成merge流程
6. 修改分支
a.) 修改分支名称:
$ git br -m <branchName>
b.) 修改当前分支远端关联:
$ git br --set-upstream-to <remote-branch>
c.) 修改指定分支远端关联:
$ git br --set-upstream <branch> <remote-branch>
7. 删除分支
a.) 删除本地分支:
$ git br -d <branch>
b.) 强制删除本地分支:
$ git br -D <branch> # 未被合并的分支被删除的时候需要强制
c.) 删除远端分支:
$ git push origin --delete <branch>
# 或:
$ git push origin :<branch> # 推送一个空分支到远端,即删除
d.) 批量删除分支:
# 删除本地
git br | grep <branch> | xargs git br -D
# 删除远程release
git br -r | grep -E 'release' | sed 's/origin\///g' | xargs -I {} git push origin :{}
8. 更新分支
从远端拉取最新的分支信息,更新本地缓存
$ git fetch -p # 更新被删除的分支
若更新时提示本地refs错误时,需要删除本地版本库上那些失效的远程追踪分支,命令如下:
$ git remote prune origin
三、查看管理
1. 查看当前状态
$ git st # 查看当前工作状态
2. 查看提交记录
a.) 查看全部提交记录:
$ git lg
b.) 查看单个文件所有记录:
$ git lg <fileName>
c.) 查看单个文件修改详情:
$ git lg -p <fileName> # 可查看比较文件历史修改记录
d.) 查看单条记录详情:
$ git show <commit-id> # 日志的hash值
e.) 查找所有包括指定字符串文件:
$ git grep -n <string> # -n:显示字符串所在的行数
3. 查看比较文件
a.) 查看比较文件:(与暂存区比较)
如果当前文件没被修改,需要查看历史修改情况,用上面的git lg -p fileName
$ git diff <fileName> # 比较当前文件和暂存区文件差异,应用在提交前确认的场景
b.) 比较两次提交记录:
$ git diff <commit-id1> <commit-id2> # 比较两次提交之间的差异
4. 查看历史操作记录
每一次当前HEAD发生改变(包括切换branch, pull, 添加新commit)一个新的纪录就会被添加到reflog
$ git reflog
四、操作管理
1. 更新
a.) 非快进更新:
$ git pull --no-ff
b.) 基于rebase:
这个命令会迫使git将远程分支上的变更同步到本地,然后将尚未推送的提交重新应用到这个最新版本,就好象它们刚刚发生一样,这样就可以避免合并以及随之而来的丑陋的合并信息
$ git pull --rebase # 避免产生无用的合并信息
若--rebase冲突了,先取消,改用git pull(不加--rebase参数),如下:
git rebase --abort
git pull
若--rebase冲突了,也可以先解决冲突,然后执行:
$ git add -A # 强制添加到
$ git rebase --continue
c.) 临时更新:(暂存)
$ git stash # 先放入暂存区
$ git pull
$ git stash pop # 恢复显示工作内容,或用git stash apply stash@{n}挑选恢复哪个
d.) 管理暂存:
$ git stash list # 显示暂存列表
$ git stash clear # 清除暂存列表
2. 提交
a.) 多个修改,只提交部分:
$ git add <file1> <file2> # 只添加要提交的到本地暂存区
$ git ci -m 'commit info' # -m处不加a
$ git push
b.) 提交全部:
$ git add . # 有新文件时,一定要
$ git ci -am 'commit info'
$ git push
c.) 追加提交:(未push到远端)
将最近一次的变更追加到最新的提交,同时也可以编辑提交信息,不产生新的提交记录。
$ git ci --amend # 如果已push到远端,不建议追加,容易跟自己冲突
$ git push
d.) 提交时绕过pre-commit验证:
$ git ci -am 'commit info' --no-verify
3. 提取
从别的分支同步一个commit到本分支
$ git cherry-pick <commit-id> # 单条
$ git cherry-pick <prev-commit-id>..<commit-id> # 多条,不包括prev-commit-id这条
# 提取一个merge提交
$ git cherry-pick -m <parent-number> <commit-id> # parent-number为主线序号,一般是第一个,也即是1
4. tag标记
tag用来标记一个版本,用于日后的恢复
# 查看所有tag
$ git tag
# 新增
$ git tag v1.0.0
# 删除
$ git tag -d v1.0.0 # 删除本地
$ git push origin :refs/tags/v1.0.0 # 删除远程
# 推送
$ git push --tags
五、恢复管理
1. 恢复本地
a.) 已修改,未暂存:
# 恢复单个文件或目录
$ git co <fileName|directory>
# 恢复全部
$ git co .
b.) 已暂存,未提交:
$ git reset HEAD^ # 向前回滚一条记录,相当于HEAD~1
$ git co .
c.) 恢复前N条:
$ git reset HEAD~n # 默认省略--soft参数,属于软恢复,n>=1整数
d.) 硬恢复:
$ git reset --hard HEAD~n|<commit-id> # 不保留当前修改,要当心,确认当前修改没有用了
2. 恢复远端
a.) 单次回滚: git revert
会产生一个新的与之前commit相反的操作,来抵消之前错误的提交。
1.) 回滚一个普通commit
$ git revert <commit-id> # 也可以多次操作,达到恢复多个的目的
$ git push
2.) 回滚一个merge
$ git show <merge-id> # 查看merge的commit-id,有一行显示:Merge: 96db08bb0 3669a27a5
# 核对一下以哪个为主线(主线的内容将会保留,而另一条分支的内容将被revert),若第一个为准,parent-number就是1
$ git revert -m <parent-number> <merge-id>
$ git push
值的注意的是:如果刚才revert掉的内容,后面如果要再合并过来,需要在之前执行revert所在的分支上再执行一次revert,否则会造成那次的内容丢失(git记忆功能):git revert <revert-commit-id>
b.) 指定位置:
$ git reset --hard <commit-id> # 恢复到当前位置
$ git push -f # 要加-f强制推送
c.) 挑选模式:
$ git rebase -i <commit-id> # 会打开编辑,剔除挑选记录
$ git push -f # 要加-f强制推送
六、其它命令
1. 临时忽略文件
a.) 忽略跟踪:
.gitignore只能忽略那些原来没有被跟踪的文件,如果文件已被纳入版本管理中,则修改.gitignore是无效的。
$ git update-index --assume-unchanged <file>
b.) 恢复跟踪:
$ git update-index --no-assume-unchanged <file>
c.) 查看被忽略的跟踪:
$ git ls-files -v|grep '^h'
d.) 另一个类似的功能:
# 忽略
$ git update-index --skip-worktree <file>
# 恢复
$ git update-index --no-skip-worktree <file>
2. 清理
a.) 移除版本控制:
$ git rm <file> --cached # -r:移除目录, --cached:保留本地的文件
b.) 清理工作树:
$ git clean -fd # 移除未跟踪的文件和目录,如果加上-n参数来先看看会删掉哪些文件
c.) gitLab拉取代码:
$ git clean -df && git reset --hard && git pull
d.) 垃圾回收:
Git 往磁盘保存对象时默认使用的格式叫松散对象(loose object)格式,当手动执行git gc 命令,或推送至远程服务器时,Git会将这些对象打包至一个叫packfile的二进制文件以节省空间并提高效率。
$ git gc --auto
$ git repack -d -l
3. 帮助
$ git help
或查看某一条指令参数:
git <command> -n
七、常见问题
1、git密钥0644权限问题:
linux服务器clone时报0644权限过大提示:WARNING: UNPROTECTED PRIVATE KEY FILE!
# 修改权限
$ chmod 0600 id_rsa*
2、忽略主机公钥确认提示:
自动化脚本第一次执行git clone时会提示主机公钥确认,解决如下:
$ echo -e 'Host * \nStrictHostKeyChecking no' > ~/.ssh/config
3、清除提交记录,创建干净仓库:
# 创建无提交记录新分支
$ git co --orphan latest_branch
# 提交信息
$ git add .
$ git ci -am 'xxx'
# 删除原分支,改名当前,并强推
$ git br -D master
$ git br -m master
$ git push -f origin master
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。