git 使用总结
git 配置
#显示目前所有配置
git config --list
#显示当前配置的用户名,本仓库没有则全局
git config user.name
#配置全局默认用户名
git config --global user.name "xxx"
#配置本仓库默认邮箱
git config --local user.email "xxx@.com"
--global
配置完成之后会在$HOME目录下生成一个.gitconfig配置文件。
--local
是将这些内容写入 .git/config
文件中。
其他个人使用偏好配置
git config --global core.editor vim
git config --global merge.tool vimdiff
git config --global color.status auto
git config --global color.branch auto
git config --global color.interactive auto
git config --global color.diff auto
git config --global push.default simple
#自定义简化命令
git config --global alias.co checkout
git config --global alias.ci commit
git config --global alias.st status
git config --global alias.last 'log -1 HEAD'
git config --global alias.unstage 'reset HEAD --'
git config --global alias.lg "log --color --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset' --abbrev-commit"
git config --global core.autocrlf false # 代码在不同的平台是否转换,二进制可能误转换
#或者 vi .gitattributes : * -text
git config --global core.quotepath false # 设置显示中文文件名
#push代码报错:error: RPC failed; curl 18 OpenSSL SSL_read: Connection was reset
git config --global http.postBuffer 524288000 #出现这种问题可能是文件太大了,调整到500M
git 基本操作
仓库相关
#创建 git 仓库
mkdir test
cd test
git init
touch README.md
git add README.md
git commit -m "first commit"
git remote add origin https://gitee.com/xxx/test.git
git push -u origin master
#已有仓库
cd existing_git_repo
git remote add origin https://gitee.com/xxx/test.git
git push -u origin master
#查看远程库的详细信息
git remote –v
#取消远程仓库关联
git remote rm origin
#更改远程仓库url
git remote set-url
#一个项目 一次提交到多个远端仓库
git remote set-url --add
#添加另一个远程仓库 分开操作
git remote add upstream https://gitee.com/xxx/test1.git
包含子项目的仓库
克隆含有子项目的仓库
git clone --recursive https://github.com/example/example.git
#or
git clone https://github.com/example/example.git
git submodule update --init --recursive
子模块操作
git submodule add https://github.com//vim vim
#初始化本地子模块配置文件
git submodule init
#更新项目,抓取子模块内容
git submodule update
#删除子模块
git rm -r submodule
基本命令
git init #把当前的目录变成可以管理的git仓库,生成隐藏.git文件。
git add XX #把xx文件添加到暂存区去。
git commit –m "x" #提交文件 –m 后面的是注释,-a 代替git add。 --amend 覆盖上次提交
git status #查看状态
git diff XX #查看XX文件修改了那些内容
git diff #工作区 vs 暂存区
git diff head #工作区 vs 版本库
git diff --cached #暂存区 vs 版本库
git rm XX #删除工作区XX并记录在暂存区 rm XX + git add XX
git rm -f XX #删除已提交在暂存区的XX并记录在暂存区
git rm --cached XX#仅删除暂存区中的XX,工作区不变。rm 删除工作区XX
git mv old new #改名 相当于 mv old new ;git rm old ;git add new
git push origin main #推送本地main分支到远程main
git pull origin main #下拉远程main分支到本地main
git log #可以查看提交历史, -n 最近几次 --stat 修的的文件 --oneline 简短id与信息
git log -p XX #XX文件历史每次修改记录 commit info和diff 不加 -p 仅 commit info
git show <commitid> <file> #看具体修改内容
git blame <file> #查看指定文件的修改记录
git fetch #从远程分支拉取代码
撤销命令
#撤销工作区文件的修改
git restore <file>
git checkout <file>
git checkout . #工作区所有修改过的文件
#暂存区的文件退回工作区
git restore --staged <file>
git reset <file>
#暂存区的所有文件退回工作区
git reset HEAD
#版本回退
#回退到上一个版本 并且不保留该版本修改内容
git reset --hard HEAD^
git reset --hard HEAD~
#回退到之前第100个版本
git reset --hard HEAD~100
#退回上一版本,保留修改的内容并提交到暂存区
git reset --soft HEAD^
#退回上一版本,但保留这次 commit 中修改的内容并在到工作区
git reset HEAD^
#回退之前版本后又后悔了,回退当前版本的未来版本。
git reset --hard <commitid>
#查看历史记录的版本号id, 以便确定要回到未来的哪个版本
git reflog
#提交一个新的版本来撤销之前的某次提交
git revert <commitid>
#提交一个新的版本来撤销一串提交,从commitid1前一个(不包括)到commitid2(包括)之间的commit
# revert 命令会对每个撤销的commit进行一次提交,-n(--no-commit) 后可以最后一起手动提交
git revert -n <commitid1>^..<commitid2>
git commit -m 'This reverts commitid1 to commitid2'
分支操作
git branch #查看当前所有的分支,-a 包括远程 -r仅远程
git branch name #创建分支
git branch –d dev #删除dev分支 未合并删除失败 用 -D 强行删除
#设置dev和远程的origin/dev 关联
git branch --set-upstream dev origin/dev
git checkout master #切换到master分支
git checkout –b dev #创建dev分支 并切换到dev分支上 = git branch dev + git checkout dev
git checkout -b x origin/xx #创建一个x分支关联远程origin/xx,名称最好一致
git checkout --orphan xx #创建孤儿分支
#提交本地的newxx分支到远程的xx分支。
git push origin newxx:xx
#删除远程分支xx
git push origin :xx
git merge dev #在当前的分支上合并dev分支
git clean
git clean <path>
#-n :显示将要被删除的文件,不会真的删除
#-d :递归子目录
#-f :强制运行,删除没有被 track 的文件,但忽略 .gitignore 包含文件
#-x :删除没有被 track 的文件,包括 .gitignore 包含文件
#-X :只删除 .gitignore 包含文件
#<path> : 指定路径,默认当前路径
#-i :进入交互模式
#注意 建议执行 git clean 命令前 先加 -n 看一下哪些会被删除
#clean.requireForce 默认为true 执行的时候 需要加 -f 或者 -n 或者-i 进入交互模式
git clean -d
#对于刚编译过的项目也非常有用
#如, 他能轻易删除掉编译后生成的 .o 和 .exe 等文件. 这个在打包要发布一个 release 的时候非常有用
git reset --hard
git clean -df
#运行后, 工作目录和缓存区回到最近一次 commit 时候一摸一样的状态。
标签操作
#列出tag标签 -l 增加过滤
git tag
git tag -l "v1.0.*"
#新建tag -a表示带备注-m备注内容
git tag v1.0
git tag -a tagName -m "a tag"
git tag tagName -f -m "new tag message"
#显示tag详细信息
git show tagName
#对某次commit 增加tag
git tag -a v1.0 9fceb02 -m "a tag"
#推送某个tag到远程
git push origin v1.0
git push --tags origin tagName
#推送所有tag到远程
git push origin --tags
#删除本地tag
git tag -d v1.0
#删除远程tag
git push origin :refs/tags/v0.1.2
git push origin :tagName
git push --delete origin tagName
stash操作
#基本
#保存工作区临时修改的内容
git stash
#恢复工作区临时修改的内容
git stash pop
#进阶
#执行存储时,添加备注,方便查找。
git stash save "save message"
#查看stash了哪些存储
git stash list
#显示做了哪些改动,默认show第一个存储 -p 显示改动内容
git stash show #指定显示第几个,stash@{$num},如第1个:git stash show stash@{0}
#恢复某个存储,但不会把存储从存储列表中删除,默认使用第一个存储,即stash@{0}
git stash apply #指定恢复第几个,stash@{$num},如第2个:git stash apply stash@{1}
#恢复之前缓存的工作目录,并将缓存中的对应stash删除,默认为第一个stash
git stash pop #指定恢复并删除第几个,stash@{$num},如:git stash pop stash@{1}
#从列表中删除某个存储
git stash drop stash@{$num}
#删除所有缓存的stash
git stash clear
git 实用操作
简单操作
#多个Commits 合并成一个, 将不想保留的记录,pick改为squash,最后还有几个pick就是合并后的几个。
git rebase -i HEAD~n #合并前n次commits为一次
git rebase -i <commitid> #合并commitid之前为一次
#修改上次提交信息中的用户名与邮箱
git commit --amend --author="xxxxx <xxx@xxx.com>" --no-edit
#修改某次commit的内容
git rebase <commitid>^ --interactive #将pick改成edit 后修改内容
git add
git commit --amend
git rebase --continue
#p、 pick=使用提交
#r、 reword=使用commit,但编辑commit消息
#e、 edit=使用提交,但停止修改
#s、 squash=使用commit,但混入前一个commit
#f、 fixup=类似于“squash”,但放弃此提交的日志消息
#x、 exec=使用shell运行命令(行的其余部分)
#d、 drop=删除提交
#建议拉取远程文件方式
git fetch + git diff orgin/xx + git merge = git pull
#强行下拉并覆盖本地文件
git fetch --all; git reset --hard origin/master ;git pull
git cherry-pick
#摘樱桃法,指定 某些 commit(尤其是前面几次的commit) 合并到到另一个分支
# -e,--edit 打开外部编辑器,编辑提交信息。
# -n,--no-commit 只更新工作区和暂存区,不产生新的提交。
# -x 提交信息的末尾追加一行(cherry picked from commit ...),方便以后查到这个提交是如何产生的。
# -s,--signoff 在提交信息的末尾追加一行操作者的签名,表示是谁进行了这个操作。
# -m /--mainline parent-number
#如果原始提交是一个合并节点,来自于两个分支的合并,那么 cherry pick 默认将失败,因为它不知道应该采用哪个分支的代码变动。1表示父分支是接受变动的分支(the branch being merged into),2表示父分支是作为变动来源的分支(the branch being merged from)。
git checkout dev
git commit -m "fix a bug" # commit id: 6102271
git checkout master
git cherry-pick 6102271
# solve conflicts
git add .
git cherry-pick --continue
使提交代码记录干净流程
git checkout master
git pull
git checkout local
#切换到local分支后, 就是修改代码
#修改完了, 就正常提交代码-------git commit
#如果有多次local分支的提交,就合并,只有一次可以不合并
git rebase -i HEAD~2 #合并提交 --- 2表示合并两个
#将master内容合并到local
git rebase master---->解决冲突--->git add .--->git rebase --continue
#再起切换到master或其他目标分支
git checkout master
#将local合并到master
git merge local
#推送到远程仓库
git push
.gitignore 的格式规范
-
所有空行或者以注释符号 # 开头的行都会被 Git 忽略。
-
可以使用标准的 glob 模式匹配。
-
匹配模式最后跟反斜杠(/)说明要忽略的是目录。
-
要忽略指定模式以外的文件或目录,可以在模式前加上惊叹号(!)取反。
所谓的 glob 模式是指 shell 所使用的简化了的正则表达式。星号(*)匹配零个或多个任
意字符;[abc] 匹配任何一个列在方括号中的字符(这个例子要么匹配一个 a,要么匹配一
个 b,要么匹配一个 c);问号(?)只匹配一个任意字符;如果在方括号中使用短划线分
隔两个字符,表示所有在这两个字符范围内的都可以匹配(比如 [0-9] 表示匹配所有 0 到
9 的数字)。
我们再看一个 .gitignore 文件的例子:
# 此为注释 – 将被 Git 忽略
*.a # 忽略所有 .a 结尾的文件
!lib.a # 但lib.a 除外
/TODO # 仅仅忽略项目根目录下的 TODO 文件,不包括 subdir/TODO
build/ # 忽略 build/ 目录下的所有文件
doc/*.txt # 会忽略 doc/notes.txt 但不包括 doc/server/arch.txt
doc/**/*.pdf # 忽略 doc/ 目录及其所有子目录下的 .pdf 文件
.gitattributes
每当有文件保存或者创建时,git 会根据指定的属性来自动地保存。
使用不同的操作系统,默认的文件结尾行就会不同。在 Windows 上默认的是回车换行(Carriage Return Line Feed, CRLF),然而,在 Linux/MacOS 上则是换行(Line Feed, LF)。
gitattributes
文件是一个简单的文本文件,它为路径名提供 attributes
,每行形式如下
pattern attr1 attr2 ...
例如:
* text=auto
# 文件的行尾自动转换。如果是文本文件,则在文件入Git库时,行尾自动转换为LF。
# 如果已经在入Git库中的文件的行尾是GRLF,则文件在入Git库时,不再转换为LF。
*.txt text
# 对于.txt文件,标记为文本文件,并进行行尾规范化。
*.jpg -text
# 对于`.jpg`文件,标记为非文本文件
*.vcproj text eol=crlf
# 对于.vcproj文件,标记为文本文件,在文件入Git库时进行规范化,行尾转换为LF。在检测到出工作目录时,行尾自动转换为GRLF。
*.sh text eol=lf
# 对于sh文件,标记为文本文件,在文件入Git库时进行规范化,即行尾为LF。在检出到工作目录时,行尾也不会转换为CRLF(即保持LF)。
*.py eol=lf
# 对于py文件,只针对工作目录中的文件,行尾为LF。
自动补全
如果你系统上安装git之后没有自动补全功能,可以按如下操作来添加补全功能,记得需要重新登录一下。
wget -O /etc/profile.d/git-completion.sh https://raw.github.com/git/git/master/contrib/completion/git-completion.bash
git 添加ssh秘钥
检查现有秘钥 :
ls -al ~/.ssh
默认为:id_rsa.pub 或者 id_ecdsa.pub 或者 id_ed25519.pub
如果提示不存在则重新生成秘钥
生成新 SSH 密钥
ssh-keygen -t ed25519 -C "your_email@example.com"
如果不支持Ed25519 算法:
ssh-keygen -t rsa -b 4096 -C "xxx@xxx.com"
三次回车:
1,回车默认文件即可 2、3回车默认无密码
将 SSH 密钥添加到 GitHub 帐户。
clip < ~/.ssh/id_rsa.pub
#复制秘钥
添加到github中的管理ssh秘钥
出现多个git秘钥时候
一个公司的git服务器,一个自己的github。
添加自己的github则先按照上面的方式生成秘钥,需要指定名字否则会覆盖公司git秘钥。这里起名id_rsa_github。把秘钥添加到github。
vi ~/.ssh/config
Host github
HostName github.com
PreferredAuthentications publickey
IdentityFile ~/.ssh/id_rsa_github
ssh -T git@github
//测试是否成功。 或者添加到git安装目录的etc/bash.bashrc文件末尾。
ssh-agent -s
ssh-agent bash
ssh-add ~/.ssh/id_rsa_github