配置
sh
git config --global user.name "Your Name"
git config --global user.email "[email protected]"
ssh-keygen -t rsa -C "[email protected]" # 生成ssh文件
git config --global http.proxy http://127.0.0.1:10809 # 代理
git config --global https.proxy http://127.0.0.1:10809 # 代理
git config --global credential.helper manager # 启用 Git 的凭据助手(记录密码)
常用命令
详情
sh
git init # git初始化
git add 1.js # 添加文件到暂存区
git add . # 添加当前文件夹的所有文件到暂存区
git commit -m "..." # 提交到分支
git commit -a -m "..." # 从工作区直接提交,跳过暂存区
git commit --amend # 合并上次的提交,即如果提交内容少了,可以用此追加提交
git rm a.txt # 从暂存区移除文件,并把工作区文件一并删除
git rm --cached a.txt # 从暂存区移除文件,不删除本地文件
git clone [url] # 克隆现有项目
git rm -r --cached . # 删除本地缓存
git status -s
?? # 尚未添加到暂存区
_M # 工作区文件修改(_表示空格)
M_ # 暂存区文件修改
A_ # 新添加到暂存区
_D # 工作区文件删除
_R # 工作区文件重命名
git mv a.txt b.txt # 暂存区和工作区文件重命名(相当于以下三条命令)
mv a.txt b.txt
git rm a.txt
git add b.txt
git log # 查看提交历史
-p # 显示每次提交的差异
-2 # 仅显示最近两次提交
--stat # 显示文件提交信息
--graph # 显示 ASCII 图形表示的分支合并历史
--since=2.weeks # 从什么日期(1.years1.days5.minutes 2019-01-12)
--until # 到什么日期
-S "aaa" # 查找某次提交记录添加或删除某些字符串的记录
-F [path] # 查看某个文件或文件夹的提交记录
--author= # 仅显示指定作者相关的提交
--pretty= # 格式化显示信息
oneline # 单行显示
short
full
fuller
format:"%h - %an, %ar : %s"
%H # commit完整哈希值
%h # commit简短哈希值
%an # 作者名字
%ae # 作者邮箱
%ad # 作者修订日期
%ar # 作者修订日期,按多久之前显示
%cn # 提交者名字
%ce # 提交者邮箱
%cd # 提交者提交日期
%cr # 提交者提交日期,按多久之前显示
%s # 提交说明
git log -S "aaa" -F [filePath] # 查找某个文件的某段代码的提交记录
git blame -L 64,66 [filePath] # 查看某个文件64到66行代码是谁改的
git reset
# 设工作区为A,暂存区为B,分支为C
git reset --soft [HEAD] # 移动分支HEAD到指定位置,不取消暂存(撤销commit命令),只修改C
git reset [HEAD] # 移动分支HEAD到指定位置,并取消暂存(撤销commit命令和add命令),修改B和C
git reset --hard [HEAD] # 移动分支HEAD到指定位置,取消暂存,并撤销本地文件的修改,修改ABC(不安全,可能会丢失版本)
git reset [file] # 取消某个文件暂存(与 git add 相反)
git reset [HEAD] [file] # 某个文件暂存区重置到指定位置,只修改B(相当于A先重置,再add到B,A再恢复)
git checkout -- [file] # 撤销文件修改
git reflog # 查找之前的记录
git remote
git remote -v # 查看当前关联的远程库(cat .git/config)
git remote add [pb] [url] # 关联远程库,pb为远程 Git 仓库简写
git remote show [pb] # 查看某个远程库信息
git remote rename [opb] [npb] # 改名
git remote rm [pb] # 移除远程库
git revert -n [HEAD] # 只撤销某一步的修改,然后重新提交
git diff [<commit-id>] [file] # 比较某文件工作区与暂存区(或指定commit-id)差异
--cached/staged [<commit-id>] [file] # 比较某文件暂存区与版本库(或指定commit-id)差异
HEAD [file] # 比较某文件工作区与版本库差异
git diff [<commit-id>] [<commit-id>] [file] # 比较某文件两个commit-id之间的差异
--stat # 不显示详细信息,只显示有多少行被改动
git difftool -x "code --wait --diff" [HEAD] [file] # 比较某个文件的某一次提交跟当前的版本差异,并用vscode显示区别
git stash
git stash save "status" # 保存当前的进度状态
git stash list # 显示保存进度列表
git stash pop "[stash_id]" # 恢复指定的进度到工作区,如果没有stash_id则使用最新的进度,会删除当前进度
git stash apply "[stash_id]" # 恢复指定的进度到工作区,如果没有stash_id则使用最新的进度,不会删除当前进度
git stash drop "[stash_id]" # 删除指定的进度到工作区,如果没有stash_id则使用最新的进度
git stash clear # 删除所有存储的进度
git update-index
git update-index --skip-worktree [file] # 忽略本地文件的修改
git update-index --no-skip-worktree [file] # 取消忽略本地文件的修改
git ls-files -v # 查看所有被忽略的文件
git cherry-pick
git cherry-pick [HEAD] # 把其他分支的某次提交复制到当前分支
git cherry-pick [b] # 把某个分支的最后一次提交复制到当前分支
git cherry-pick [HEAD] [HEAD] # 多个提交
git cherry-pick [HEAD1]..[HEAD3] # HEAD1到HEAD3,不包括HEAD1
git cherry-pick [HEAD1]^..[HEAD3] # HEAD1到HEAD3,包括HEAD1
git show [<commit-id>]
git pull -f origin dev:dev # git强制拉取代码并覆盖本地,git pull -f 远程主机名 远程分支名:本地分支名
git log美化
git log --oneline --graph --decorate
git log --graph --decorate --format=format:'%C(bold yellow)%h%C(reset) - %C(bold cyan)%aD%C(reset) %C(bold cyan)(%cr)%C(reset) %C(bold yellow)%d%C(reset)%n %C(bold green)%s%C(reset) - %C(bold white)%an%C(reset)%n'
分支
sh
git branch # 查看当前分支
[b] # 创建分支
-d [b] # 删除分支(未合并的分支会删除失败)
-D [b] # 强制删除分支
-v # 查看每个分支的最后一次提交
--merged # 查看哪些分支已经合并到当前分支
--no-merged # 查看所有包含未合并工作的分支
git checkout
[b] # 切换分支
-b [b] # 创建并切换分支
[HEAD] # 检出分支
git merge [b] # 合并某分支到当前分支
git checkout -b 本地分支名 origin/远程分支名 # 从远程分支拉取本地没有的分支
git push origin --delete [b] # 删除远程分支
变基
拉取代码时变基
- 当本地提交代码之后再拉取代码时会产生类似如图的效果,继续执行
git pull
便会产生merge - 这时可以使用
git pull --rebase
便不会产生merge了 - 如果出现冲突,可以先解决冲突,然后执行
git rebase --continue
,若要取消操作,则执行git rebase --abort
- 两者的过程如下:
git pull
是先git fetch
,然后git merge origin/master
git pull --rebase
是先git fetch
,然后git rebase origin/master
- 全局设置,
git config --global --add pull.rebase true
,即执行git pull
自动执行git pull --rebase
- 取消,
git config --global --unset pull.rebase
两个分支的变基
test分支的代码合并到master分支
shgit checkout test git rebase master git checkout master git merge test
同一个分支变基
删除某次提交
- 复制删除的那次提交之前的commitId
git rebase -i [commitId]
- 修改需要删除的commit之前的pick为drop
- 如果是vim编辑器,则输入i为编辑,按esc键为退出编辑状态,wq为保存并退出
- 如果是nano编辑器,则ctrl+x,然后输入y,再按entry为保存并退出
- 拉取变基之后的代码
git pull --rebase
- 修改默认编辑器为vim
git config ---global core.editor vim
- 产生的提交数的原因:
- drop之前的不会修改commitId
- drop之后的会修改commitId,则该修改也会变,即会产生提交
- 指令类型
- pick:保留该commit(缩写:p)
- reword:保留该commit,但我需要修改该commit的注释(缩写:r)
- edit:保留该commit, 但我要停下来修改该提交(不仅仅修改注释)(缩写:e)
- squash:将该commit和前一个commit合并(缩写:s)
- fixup:将该commit和前一个commit合并,但我不要保留该提交的注释信息(缩写:f)
- exec:执行shell命令(缩写:x)
- drop:我要丢弃该commit(缩写:d)
整合分支的修改(合并test分支到master)
合并分支(
git merge test
)变基(提交历史可能会丢失)
shgit checkout test git rebase master git checkout master git merge test
不同之处:合并分支的历史记录为并行的,变基的历史记录为串行的
注意:不要对在你的仓库外有副本的分支执行变基
补丁
sh
git format-patch [HEAD] -1 # 某次提交
git format-patch [HEAD] [HEAD] # 某两次提交之间的所有patch
git diff [HEAD] [HEAD] > [file.diff] # 生成diff文件
git apply --check [file.patch|diff] # 检查能否打补丁
git apply [file.patch|diff] # 打补丁
git am [file.patch|diff] # 打补丁
git远程分支
当从远程库克隆时,会为你自动将其命名为 origin(
git clone -o [test] [url]
,可以改为test),拉取它的所有数据,创建一个指向它的 master 分支的指针,并且在本地将其命名为 origin/master(跟踪分支)。Git 也会给你一个与 origin 的 master 分支在指向同一个地方的本地 master 分支。
本地提交的时候master指针移动,但是origin/master指针不会移动
sh> a=>b=>c=>d=>e # 远程分支,本地在c处克隆,远程继续提交d和e,远程master指向e处</br> > a=>b=>c # 本地origin/master指向c处,只要不与服务器连接,指针不移动</br> > a=>b=>c=>f=>g # 本地master分支初始指向c处,继续提交f和g,master指向g处
git fetch origin: 获取本地没有的远程库origin数据,移动 origin/master 指针指向新的、更新后的位置
sh> a=>b=>c=>d=>e # 远程分支,本地在c处克隆,远程继续提交d和e,远程master指向e处</br> > a=>b=>c=>d=>e # 本地origin/master指针移动到远程origin最新处,指向e</br> > a=>b=>c=>f=>g # 本地master分支初始指向c处,继续提交f和g,master指向g处
git merge origin/master
: 合并到当前分支git checkout -b newBranch origin/master
: 新建分支,并指向跟踪分支的位置(跟踪分支和分支不同的是只有一个指针,不含可编辑的副本)git push origin --delete master
: 删除远程分支
git远程分支合并到本地
sh
git remote add test [url]
git fetch test
git checkout -b master1 test/master
git checkout master
git merge master1
git配置自定义服务器
sh
useradd git # 管理员创建用户
passwd git # 设置git用户密码
su git # 切换git用户
mkdir .ssh
chmod 700 .ssh
cd .ssh
touch authorized_keys # 创建保存公钥的文件
chmod 600 authorized_keys
vi authorized_keys # 把公钥写进文件(如果用户的公钥不在文件中,则每次需要输入登录密码)
cd /home/git # 回到主目录
git init --bare test.git # 新建空仓库
本地测试
git remote add local git@ip:/home/git/test.git # 关联远程库
git push local master # 本地推送
GitWeb
sh
yum install git-instaweb # 安装
git instaweb -p 3000 # 修改监听端口(先进入仓库所在目录)
git instaweb --start # 启动服务
GitLab基本命令
sh
gitlab-ctl reconfigure # 重启配置,并启动gitlab服务
gitlab-ctl start # 启动所有
gitlab-ctl restart # 重新启动GitLab
gitlab-ctl stop # 停止所有
gitlab-ctl status # 查看服务状态
gitlab-ctl tail # 查看Gitlab日志
vim /etc/gitlab/gitlab.rb # 修改默认的配置文件
git服务器hook配置
同步服务器的git仓库与某个文件夹的代码,即提交代码便同步该文件夹
- 修改
hook/post-update
文件,添加git --work-tree=/web/docs checkout -f
修改git用户禁止登录
git:x:1003:1003::/home/git:/usr/bin/git-shell
git不常用代码
git文件夹修改大小写
git 在windows和mac下不区分大小写,如果直接修改文件名大小写,则提交不上去,可以使用 git mv
修改
sh
git mv ./test ./aaa
git mv ./aaa ./Test
从git仓库删除多次提交的文件
sh
git filter-branch --force --index-filter 'git rm --cached --ignore-unmatch [相对路径的文件名]' --prune-empty --tag-name-filter cat -- --all
git push origin master --force --all
git push origin master --force --tags
rm -rf .git/refs/original/
git reflog expire --expire=now --all
git gc --prune=now
git gc --aggressive --prune=now
git不在目录中执行命令
git -C D:\program\docs log
git -C D:\program\docs reset --hard [hash]
git错误
- 拉代码或者合并代码报
fatal: refusing to merge unrelated histories
,再后面添加参数--allow-unrelated-histories
git记录密码
- 创建
.git-credentials
文件 - 输入
https://username:[email protected]
,username 和 password 分别是你的 GitHub 用户名和密码。 - 允许命令
git config --global credential.helper store
powershell操作git
单条
ps1git branch --show-current # 获取当前分支 git branch --list dev # 判断本地dev分支是否存在 git status --porcelain # 判断仓库是否有未提交的更改
获取所有远程分支,过滤掉 HEAD 和当前的分支
ps1# 获取所有远程分支,过滤掉 HEAD 和当前的分支 $remoteBranches = git branch -r | Where-Object { $_ -notmatch '->' } # 遍历所有远程分支并在本地创建对应分支 foreach ($remoteBranch in $remoteBranches) { $branchName = $remoteBranch.Trim() -replace 'origin/', '' # 检查本地分支是否已经存在 if (-not (git branch --list $branchName)) { # 创建本地分支并关联远程 git branch --track $branchName $remoteBranch.Trim() } }