git常用命令介绍,git使用技巧和使用优化。
Git 常用命令
git init
git init here -- 创建本地仓库
git remote add origin git@github.com:用户名/仓库名.git
-- 把本地仓库和远程仓库关联起来, 如果不执行这个命令的话,每次 push 的时候都需要指定远程服务器的地址git config
global 变量:
git config --global user.name "xiexianbin" -- 配置用户名,上传本地 repository 到服务器上的时候,在 Github 上会显示这里配置的上传者信息
git config --global user.email "me@xiexianbin.cn" -- 配置邮箱
git config core.filemode true -- 配置文件权限mode敏感,在git管理的目录下执行,cat .git/config 查看
git config --global core.fileMode false -- 同上,全局生效
git config --list -- 查看配置列表local 变量:
git config user.email "me@xiexianbin.cn" -- 配置邮箱,可以在 .git/config 中查看对应配置git clone
git clone <git url or git path> [--depth n] [path]
# --depth 后如何变成 clone 全量代码
git fetch --unshallow- 镜像仓库到本地
$ git clone --mirror https://xxx/xxx.git
# clone 后的目录结构
$ ls xxx.git
branches config description HEAD hooks info objects packed-refs refs
# 从此镜像 clone
$ git clone /root/xxx.git/
Cloning into 'xxx'...
done.
$ cd xxx
$ git remote -v
origin /root/xxx.git/ (fetch)
origin /root/xxx.git/ (push)- 用户名密码
https://<username>@<git_url>- SSH key
ssh://<username>@<git_url>- personal access tokens
获取 github personal access tokens
settings > developer settings > personal access tokens > generate new tokengit clone http://<username>:<access tokens>@<git_url>
git clone https://<token>@github.com/owner/repo.git- 或使用 ~/.netrc 配置
git clone 子目录
仅 clone 一个 git 项目的子目录
mkdir <repo>
cd <repo>
git init
git remote add -f origin <url>
# 配置要 clone 子目录
git config core.sparseCheckout true // 等价于 git sparse-checkout init
echo "some/dir/" >> .git/info/sparse-checkout // 等价于 git sparse-checkout set "some/dir/"
# 查看要 clone 子目录,等价于 cat .git/info/sparse-checkout
git sparse-checkout list
# clone
git pull origin <target-branch> [--depth=1]git commit
git commit -m "注释" -- 把本机缓存中的内容提交到本机的 HEAD 里面
git commit -sv -m "xxx" --date="2018-01-01T00:00:00+0800" -- 指定提交的时间
# 自动修改时间
git commit --amend --date="$(date -R)"
git commit --amend --date="`date -R`:git revert
回滚一个提交
git revert <commit-id>git pull
git pull origin master- pull 子目录
mkdir <repo> && cd <repo>
git init
git remote add -f origin <url>
git config core.sparseCheckout true
echo "some/dir/" >> .git/info/sparse-checkout
echo "another/sub/tree" >> .git/info/sparse-checkout
git pull origin maingit fetch
git pull=git fetch+git merge- 配置
git config pull.rebase true可以实现pull时自动rebase
git fetch- fetch 下载远程仓库 refs 信息到
.git/refs/remotes,下载缺失的 object,同时更新.git/FETCH_HEAD(示例:373c59b0f070213c63b4d007a3d3fcf9502723d7 branch 'main' of github.com:xiexianbin/xiexianbin.github.io),即本地当前 fetch 的位置- 信息指向:
.git/refs/remotes/origin/HEAD->.git/refs/remotes/origin/main->id
- 信息指向:
git fetch origin main不会自动合并: 非常重要的一点是,git fetch 不会自动将这些新的更改合并(merge)或变基(rebase)到你当前工作的本地分支(比如你当前的 main 分支)。它只是安全地把远程的最新代码拿到本地,让你自己决定何时以及如何合并git merge origin/main将远程跟踪分支(例如 origin/main)的更新合并到当前本地分支(例如 main)
git push
git add
git add -A -- 将改动添加到本地仓库中
git rm xxx -- 从本地仓库中删除指定文件
git rm -r xxx -- 从本地仓库中删除指定文件夹
git push origin master -- 把本地的 commit push 到远程仓库中或
git push origin HEAD:master指定分支 push:
git push origin HEAD:stable/jdk8git log/show
git show <commit-id> # 查看某次提交的内容
git log --pretty=oneline <file-path> # 查看某文件的修改历史
git log --stat <commit-id> # 仅显示修改行数
git log -- <file> # 只显示某文件的提交日志
git log --oneline -n 1 # 日志只显示一行
# 查看某个分支或 tag 的某个文件内容
git show main:.gitignoregit branch
# 查看所有分支
git branch -a
# 删除本地分支,-D 为强制删除
git branch -d [branchName]
git branch -D [branchName]
# 删除 origin 分支
git push origin --delete [branchName]
git push origin :[branchName]
# 清除 origin 不存在,单本地存在的分支
git remote prune origingit tag
git tag -l
# 显示离当前提交最近的标签
git describe --tags获取当前分支的 tag 或 branch
function current_branch () {
local folder="$(pwd)"
[ -n "$1" ] && folder="$1"
git -C "$folder" rev-parse --abbrev-ref HEAD | grep -v HEAD || \
git -C "$folder" describe --exact-match HEAD || \
git -C "$folder" rev-parse HEAD
}
# current_branch .git -C指定 git 的根目录
git remote
查看源端
git remote show origin清除已删除远程分支
删除远端不存在的本地分支
git remote prune origin或
git fetch -p查看命令
git remote show origingit worktree
# 指定目录创建新分支
git worktree add ../project-feature-a -b feature-a
# 指定现有 worktree
git worktree add ../project-bugfix-a bugfix-a
# 列出所有 worktree
git worktree list
# 删除一个 worktree
git worktree remove ../project-feature-a为文件添加执行权限
# 新文件
git add --chmod=+x -- entrypoint.sh
# 已有问题
git update-index --chmod +x entrypoint.sh
# 若不生效,直接使用 chmod a+x entrypoint.sh; git add .
# 查看文件权限
git ls-files --stagegit describe
git describe 命令显示离当前提交最近的标签
git describe [--all] [--tags] [--contains] [--abbrev=<n>] [<commit-ish>…]
git describe [--all] [--tags] [--contains] [--abbrev=<n>] --dirty[=<mark>]- 示例
$ git describe --tags
v2.2.12-8-g040935c说明:
v2.2.12tag 名称8表示自v2.2.12后有 8 次提交(commit)g040935cg为 git 的缩写040935c为当前提交的 commit id
git rev-list
按时间顺序倒序列出提交对象
# 按时间倒序列出所有 commit id
git rev-list --all
# 按时间倒序列出最后一次提交的 commit id
git rev-list --all -n 1
# 按时间倒序列出最后一次提交的 commit id 缩写
git rev-list HEAD --abbrev-commit --max-count=1
# 和 submodule 结合使用
git submodule foreach git rev-list HEAD --abbrev-commit --max-count=1git rev-parse
# 显示分支
git rev-parse --symbolic --branches
# 显示tag
git rev-parse --symbolic --tags
# 显示所有
git rev-parse --symbolic --glob=refs/*
# 显示 hash 值
git rev-parse HEAD
git describe
git rev-parse master refs/heads/maingit show-ref
查看 ref
git show-refgit ls-files
列出 git 未管理的文件
git ls-files --others --exclude-standardgit ls-remote
列出远程存储库中的引用
git ls-remote --heads --tags origingit merge
将两个或多个分支历史合并在一起,以从 dev 向 main 分支合并为例:
# 首先切换到dev
git checkout dev
# 获取最新 dev 代码
git pull
# 切换到main分支
git checkout main
# 把 dev 分支的代码merge到 main 分支
git merge dev
# 推送到远程 main 分支
git pushgit format-patch 补丁制作命令
使用 git format-patch 生成相关 patch,示例如下:
# 最近1次提交
git format-patch HEAD^
# 最近2次提交
git format-patch HEAD^^
# 最近3次提交
git format-patch HEAD^^^
# 最近4次提交
git format-patch HEAD^^^^
# 生成指定(不含)提交之后的所有提交
git format-patch <commit>
# 生成指定(含)提交
git format-patch -1 <commit>
# 生成指定(含)提交之前的n次提交
git format-patch -n <commit>
# # 生成两个commit间的修改的patch(包含两个commit. <r1>和<r2>都是具体的commit号)
git format-patch <r1>..<r2>
# 生成从根到r1提交的所有patch
git format-patch --root <r1>
# 打包最近的 3 个 commit
git format-patch HEAD~3 --stdout > bundle.patch
# 将最近 3 个 commit 的变动合并成一个 patch
git diff HEAD~3 HEAD > all_changes.patchgit apply/git am
git apply 和 git am 都是用于将补丁(patch)应用到当前代码库的命令,但它们的设计目的、输入格式以及执行结果有显著的区别。
一句话总结:
git apply是用来打补丁的(修改文件内容,不产生提交)。git am是用来重放提交的(恢复完整的 Commit 历史)。
详细对比表
| 特性 | git apply | git am (Apply Mailbox) |
|---|---|---|
| 主要用途 | 应用差异文件,修改工作区文件 | 应用由 format-patch 生成的补丁,重建提交 |
| 输入来源 | 通常是 git diff 生成的普通 patch 文件 |
通常是 git format-patch 生成的包含元数据的 patch 文件 |
| 执行结果 | 只修改文件(处于 Modified 或 Staged 状态),不创建 Commit | 直接创建 Commit(代码库中会增加新的提交记录) |
| 提交信息 | 丢失(不包含作者、时间、提交说明) | 保留(完整保留原作者、提交时间、提交说明) |
| 冲突处理 | 失败则不做任何更改(除非强制),比较原子性 |
遇到冲突会暂停,解决后使用 git am --continue 继续 |
| 类比 | 增强版的 Linux patch 命令 |
相当于 git cherry-pick 的文件版 |
- 参考 patch 补丁命令用法
# 生成补丁
git diff > test.patch
# 查看patch的情况
git apply --stat 0001-xxx.patch
# 恢复补丁
git apply test.patch
# 检查patch是否能够打上
# 如果没有任何输出,则说明无冲突,可以打上
# 如果出现patch does not apply则表示有冲突,则需要git apply --reject xxx
git apply --check 0001-xxx.patch
# 强制打补丁,如果生成*.rej文件则需要手动打补丁
git apply --reject 0001-xxx.patch
git am 0001-xxx.patch
# 添加-s或者--signoff,还可以把自己的名字添加为signed off by信息,作用是注明打patch的人是谁,因为有时打patch的人并不是patch的作者
git am --signoff 0001-xxx.patch
# 将路径~/patch-set/*.patch 按照先后顺序打上
git am ~/patch-set/*.patch
# 当git am失败时,用以将已经在am过程中打上的patch废弃掉
git am --abort
# 当git am失败,解决完冲突后,这条命令会接着打patch
$ git am --resolvedgit ls-files
查看暂存区中的文件
git ls-filesgit ls-tree
List the contents of a tree object
$ git help ls-tree
-r(递归)参数表示递归遍历整个树形结构。
--full-tree 参数表示显示完整的树形结构,包括所有子目录和文件。
-t 参数表示在输出中显示文件类型(blob、tree 或者是 commit)。
-z 参数表示以 null 结尾输出,方便使用程序进行处理。
--abbrev=<n> 参数表示对 SHA-1 摘要显示前 n 位。
--long 参数表示使用长格式输出,包括文件的大小,权限信息等。
<tree-ish> 表示需要显示的树形结构的引用,可以是一个分支名称、标签名称或者是一个提交的 SHA-1 摘要。
<path>... 表示需要显示的目录或文件的路径,如果未指定,则显示整个树形结构。- 递归查看文件的 commit-id 示例
$ git ls-tree -r main
...
160000 commit 2e3535efbc81aed06994c845d6c289d05de96e2e themes/hugo-bootstrap-xgit rev-list
Lists commit objects in reverse chronological order 按时间倒序列出提交对象
git rev-list HEAD --abbrev-commit --max-count=1配置仓库级别SSH key认证
- 根据 host 使用特定的SSH Key提交GIT
$ cat ~/.ssh/config
Host github.com
HostName github.com
User git
IdentityFile /path-to/.ssh/id_rsa
IdentitiesOnly yes- 使用 git 命令配置
# 配置
git config core.sshCommand "ssh -i ~/.ssh/id_rsa"
# 查看
git config --get core.sshCommand.gitignore 文件
github 官方维护了一个仓库,专门管理 gitignore 配置:
https://github.com/github/gitignore作用:忽略指定的内容
使用:
- 在本地仓库根目录创建
.gitignore文件 - 过滤文件和文件夹:
[Tt]emp/过滤Temp\temp文件夹;*.suo过滤.suo文件; - 不过滤文件和文件夹:
!*.c
表情
git 提交可以使用如下命令填加表情:
git commit -m ":smile: your message"
git commit -m ":books: documentation is completed"https://www.webfx.com/tools/emoji-cheat-sheet/
加密
git 加密有很多方式
- 与 keybase 结合
- Git 文件加密
- Sealed-secret
- vault 等
问题
多邮箱问题
remote pull push 的时候会有问题,因为设置了 pull 的时候识别的是邮箱,2 个 github 账号,2 个邮箱,我们自然不能使用 global 的 user.email,修复方式:
首先,取消 global:
git config --global --unset user.name
git config --global --unset user.email然后,设置每个项目 repo 的自己的 user.email
cd project
git config user.email "me@xiexianbin.cn"
git config user.name "xiexianbin"可以在.git/config 中查看对应的设置。
Git 中文乱码
在 terminal 中执行:
git config --global core.quotepath false如果解决不了,若采用 oh-my-zsh 可以进行如下配置:
- 打开
oh-my-zsh配置文件~/.zshrc - 在文件最后面添加如下代码:
export LC_ALL=en_US.UTF-8
export LANG=en_US.UTF-8- 重启下终端或输入
source ~/.zshrc
git remote: HTTP Basic: Access denied 错误
git 操作报错误:git remote: HTTP Basic: Access denied 错误
解决方法:
- 密码修改导致问题,重新输入账号密码即可,命令:
git config --system --unset credential.helper- 清空密码认证信息,重新输入,命令:
git config --global http.emptyAuth trueSSL: no alternative certificate subject name matches target host name
git config --global http.sslVerify falsegit pull index-pack failed
用 git pull 的时候,经常会遇到这样的错误:
fatal: early EOF
fatal: index-pack failed有几处设置可以尝试着去解决这个问题。首先找到 gitconfig 文件。它的路径在:
*[git installed path]*/etc/gitconfig以管理员模式打开这个文件,在[core]部分加上这一句:
compression = 0这代表不压缩,会引起一定的性能问题。如果之后不再出现以上的错误,可以再去掉这一行。如果还不行,有可能是因为存在 Git 上的工程太大了,这时候需要把本地的限制调高一些。还是在[core]部分,加上这两行:
packedGitLimit = 512m
packedGitWindowSize = 512m在[pack]部分加上这三行:
deltaCacheSize = 2048m
packSizeLimit = 2048m
windowMemory = 2048m大小根据你的实际情况来填写
换行符问题
- 回车换行
- CR 回车
- LF 换行
- Windows/Dos CRLF \r\n
- Linux/Unix LF \n
- MacOS CR \r
- Git 配置
推荐设置:
git config --global core.autocrlf input
git config --global core.safecrlf warn- CRLF 设置
提交时转换为 LF,检出时转换为 CRLF:
git config --global core.autocrlf true提交时转换为 LF,检出时不转换:
git config --global core.autocrlf input提交检出均不转换:
git config --global core.autocrlf false- SafeCRLF 设置
拒绝提交包含混合换行符的文件:
git config --global core.safecrlf true允许提交包含混合换行符的文件:
git config --global core.safecrlf false提交包含混合换行符的文件时给出警告:
git config --global core.safecrlf warnGit Push: Error writing request body to server
- 问题描述
- Git Push 错误"Error writing request body to server"
默认 Git 设置 http post 的缓存为 1M
- 解决方法
增加 http post 缓存, 如果使用 git 命令,设置参数命令如下:
#增加为 500MB
git config http.postBuffer 524288000如果使用的是 Eclipse Git 插件,则需要在 Window -> Preferences 中找到 Team -> Git -> Configuration 配置界面,在 System Settings Tab 页中 点击 “Add Entry…” 按钮来添加一个配置项:
key为: http.postBuffer value为:524288000ssh 链接慢
修改:/etc/ssh/sshd_config
UseDNS no # 指定 sshd 是否对远程主机名进行反向解折,以检查主机名与其IP地址真实对应,默认值为 yes
# GSSAPI options
GSSAPIAuthentication no
GSSAPICleanupCredentials no删除 git 密码
$ git credential-manager uninstall
git: 'credential-manager' is not a git command. See 'git --help'.
The most similar command is
credential-manager-coreF&Q
failed to push some refs
- 错误日志
$ git push origin master
Username for 'https://github.com': REDACTED
Password for 'https://REDACTED@github.com':
To https://github.com/REDACTED.git
! [rejected] master -> master (non-fast-forward)
error: failed to push some refs to 'https://github.com/REDACTED.git'
hint: Updates were rejected because the tip of your current branch is behind
hint: its remote counterpart. Integrate the remote changes (e.g.
hint: 'git pull ...') before pushing again.
hint: See the 'Note about fast-forwards' in 'git push --help' for details.- 解决方法,使用如下命令可以将仓库已经提交的合并到本地
git pull --rebase origin masterskip SSL verify
- 解决 CA 引起的问题
fatal: unable to access 'https://xxx.git/': server certificate verification failed. CAfile: none CRLfile: none
export GIT_SSL_NO_VERIFY=1
或
git config --global http.sslVerify falseRPC failed; curl 56 OpenSSL SSL_read: Connection was reset
- error: RPC failed; curl 56 OpenSSL SSL_read: Connection was reset, errno 10054
远程仓库文件太大导致,设置 http.postBuffer(示例为 500M) 参数:
git config http.sslVerify “false” git config –global http.postBuffer 524288000
最近更新
最新评论