常用git命令
码不停提
Git 是一个分布式版本控制系统,用于追踪文件变更并协作开发。开发者可创建分支进行独立修改,通过提交(commit)记录变更,合并(merge)分支整合代码。其高效分支管理、快速性能及开源特性,使其成为软件开发的核心工具。
码不停提
Git 是一个分布式版本控制系统,用于追踪文件变更并协作开发。开发者可创建分支进行独立修改,通过提交(commit)记录变更,合并(merge)分支整合代码。其高效分支管理、快速性能及开源特性,使其成为软件开发的核心工具。
首先默认你已经知道什么是git,并且已经知道怎么安装git。本文只对常用 git 命令做讲解。
git config --global user.name "information"
git config --global user.email "cdinformation@163.com"
- 设置用户名和邮箱,用户名是你在commit的时候,显示的你的名字;
- 邮箱,最好填写你的git账号邮箱,在github上,只有填写github账户邮箱,你的commit才会被计入你的贡献;
- 这些配置的参数是保存在你的本地git仓库的config文件中的;/你的项目/.git/config (这个文件),其中.git是一个隐藏目录;
Git的基本操作流程:
- 从远端clone(克隆)或是pull(拉取)代码到本地;
- 对代码进行修改
- 将代码添加到本地仓库: 需要两部操作
- step 1: git add {需要加入本地仓库的文件}
- step 2: git commit -m "{对修改进行备注}"
- 将代码推送(push)到远端(origin)仓库
什么时候用clone?
- 你是一个新员工,刚到公司,你本地电脑上还没有代码仓库,当你的领导分配给你git账号权限,并且给你远程仓库地址的时候,你就可以把远程仓库clone到本地;
什么时候用pull ?
- 当你本地已经有 git 仓库的时候,就可以进入到 git 仓库那个目录,使用 git pull(拉取远程的代码)
- 不是每次git pull 都能拉取新的代码到本地
- 如果远程代码和本地代码是相同的,则会提示
Already up to date.- 如果远程代码有改动,本地代码无改动,则会拉取远程最新代码到本地,并与本地代码合并
- 如果远程代码和本地代码都有改动,则会检测代码是否有冲突(conflict),有冲突则需要先解决冲突,再pull,没有冲突则可以直接合并(merge)。
- 在每次准备修改代码之前,都进行一次pull是一个好习惯
- 在每次改完代码,做push之前,都做一次pull也一个好习惯
git init . //初始化
git branch dev //创建本地dev分支
git add newfile //提交新文件到暂存区
git commit -m 'add new file' //提交到本地仓库
git remote add origin git@xx.com:demo.git //添加远程仓库地址
git fetch origin -p // 同步本地远程仓库镜像
git merge origin/dev // 合并远端dev分支
git push origin dev:dev //把本地dev 推送到远端
git branch feature-new origin/dev // 基于远端dev 创建新分支 feature-new
git add newfeature.txt //提交新文件到暂存区
git commit -m ' finish new feature' //提交到本地仓库
git checkout dev // 切换回本地dev分支
git merge newfeature // 本地dev分钟 合并 newfeature分支
git brand -d newfeature // 合并完成,删除 newfeature 分支
git push origin :newfeature // 删除远端 newfeature 分支
git fetch origin -p // 同步远端代码到本地
git merge origin/dev // 合并
git push origin dev:dev // 推送本地dev到远端dev

# 在当前目录新建一个 Git 代码库
$ git init
# 新建一个目录,将其初始化为 Git 代码库
$ git init [project-name]
# 下载一个项目和它的整个代码历史
$ git clone [url]
Git 的设置文件为.gitconfig,它可以在用户主目录下(全局配置),也可以在项目目录下(项目配置)。
# 显示当前的 Git 配置
$ git config --list
# 编辑 Git 配置文件
$ git config -e [--global]
# 设置提交代码时的用户信息
$ git config [--global] user.name "[name]"
$ git config [--global] user.email "[email address]"
# 添加指定文件到暂存区
$ git add [file1] [file2] ...
# 添加指定目录到暂存区,包括子目录
$ git add [dir]
# 添加当前目录的所有文件到暂存区
$ git add .
# 删除工作区文件,并且将这次删除放入暂存区
$ git rm [file1] [file2] ...
# 停止追踪指定文件,但该文件会保留在工作区
$ git rm --cached [file]
# 改名文件,并且将这个改名放入暂存区
$ git mv [file-original] [file-renamed]
# 提交暂存区到仓库区
$ git commit -m [message]
# 提交暂存区的指定文件到仓库区
$ git commit [file1] [file2] ... -m [message]
# 提交工作区自上次 commit 之后的变化,直接到仓库区
$ git commit -a
# 提交时显示所有 diff 信息
$ git commit -v
# 使用一次新的 commit,替代上一次提交
# 如果代码没有任何新变化,则用来改写上一次 commit 的提交信息
$ git commit --amend -m [message]
# 重做上一次 commit,并包括指定文件的新变化
$ git commit --amend ...
# 列出所有本地分支
$ git branch
# 列出所有远程分支
$ git branch -r
# 列出所有本地分支和远程分支
$ git branch -a
# 新建一个分支,但依然停留在当前分支
$ git branch [branch-name]
# 新建一个分支,并切换到该分支
$ git checkout -b [branch]
# 新建一个分支,指向指定 commit
$ git branch [branch] [commit]
# 新建一个分支,与指定的远程分支建立追踪关系
$ git branch --track [branch] [remote-branch]
# 切换到指定分支,并更新工作区
$ git checkout [branch-name]
# 建立追踪关系,在现有分支与指定的远程分支之间
$ git branch --set-upstream [branch] [remote-branch]
# 合并指定分支到当前分支
$ git merge [branch]
# 选择一个 commit,合并进当前分支
$ git cherry-pick [commit]
# 删除分支
$ git branch -d [branch-name]
# 删除远程分支
$ git push origin --delete
$ git branch -dr
# 列出所有 tag
$ git tag
# 新建一个 tag 在当前 commit
$ git tag [tag]
# 新建一个 tag 在指定 commit
$ git tag [tag] [commit]
# 查看 tag 信息
$ git show [tag]
# 提交指定 tag
$ git push [remote] [tag]
# 提交所有 tag
$ git push [remote] --tags
# 新建一个分支,指向某个 tag
$ git checkout -b [branch] [tag]
# 显示有变更的文件
$ git status
# 显示当前分支的版本历史
$ git log
# 显示 commit 历史,以及每次 commit 发生变更的文件
$ git log --stat
# 显示某个文件的版本历史,包括文件改名
$ git log --follow [file]
$ git whatchanged [file]
# 显示指定文件相关的每一次 diff
$ git log -p [file]
# 显示指定文件是什么人在什么时间修改过
$ git blame [file]
# 显示暂存区和工作区的差异
$ git diff
# 显示暂存区和上一个 commit 的差异
$ git diff --cached []
# 显示工作区与当前分支最新 commit 之间的差异
$ git diff HEAD
# 显示两次提交之间的差异
$ git diff [first-branch]...[second-branch]
# 显示某次提交的元数据和内容变化
$ git show [commit]
# 显示某次提交发生变化的文件
$ git show --name-only [commit]
# 显示某次提交时,某个文件的内容
$ git show [commit]:[filename]
# 显示当前分支的最近几次提交
$ git reflog
# 下载远程仓库的所有变动
$ git fetch [remote]
# 显示所有远程仓库
$ git remote -v
# 显示某个远程仓库的信息
$ git remote show [remote]
# 增加一个新的远程仓库,并命名
$ git remote add [shortname] [url]
# 取回远程仓库的变化,并与本地分支合并
$ git pull [remote] [branch]
# 上传本地指定分支到远程仓库
$ git push [remote] [branch]
# 强行推送当前分支到远程仓库,即使有冲突
$ git push [remote] --force
# 推送所有分支到远程仓库
$ git push [remote] --all
# 恢复暂存区的指定文件到工作区
$ git checkout [file]
# 恢复某个 commit 的指定文件到工作区
$ git checkout [commit] [file]
# 恢复上一个 commit 的所有文件到工作区
$ git checkout .
# 重置暂存区的指定文件,与上一次 commit 保持一致,但工作区不变
$ git reset [file]
# 重置暂存区与工作区,与上一次 commit 保持一致
$ git reset --hard
# 重置当前分支的指针为指定 commit,同时重置暂存区,但工作区不变
$ git reset [commit]
# 重置当前分支的 HEAD 为指定 commit,同时重置暂存区和工作区,与指定 commit 一致
$ git reset --hard [commit]
# 重置当前 HEAD 为指定 commit,但保持暂存区和工作区不变
$ git reset --keep [commit]
# 新建一个 commit,用来撤销指定 commit
# 后者的所有变化都将被前者抵消,并且应用到当前分支
$ git revert [commit]
# 生成一个可供发布的压缩包
$ git archive
冲突解决
- 当二个人同时更改了文件的某些部分,合并时将会出现冲突,此时,可找到另外一个人,仔细对比代码,手动删除不需要的代码,保留合理代码,然后提交 两个可能用到的命令
git checkout --ours conflict.php //使用自己分支的代码,抛弃合并过来冲突
git checkout --theirs conflict.php //使用合并分支的代码,抛弃自己冲突这块更改的代码
什么是 commit ? 内容怎么写
- commit 是备注本次修改的内容便于以后查看改动记录
- git commit 回答三个问题 修改是什么?
- 用什么方法修改的? 这些方法可能影响什么地方?
- 每次commit只能包含一个改动
- 每次commit必须单独写提交信息
查看git 记录
- 通过git log查看最近的commit记录,在记录列表界面,输入q可退过查看记录列表
- 通过git gui可打开GUI界面,在GUI面板上可以看所有提交记录
学会git status查看文件状态
- 先用git status查看一下改动的文件状态;
- 状态为红色,表示修改未添加到暂存区
- 装态为绿色,表示文件已添加到暂存区
如果将暂存区的文件还原(把绿色的文件还原成红色)
- 通过
git reset命令可以将git status中显示"绿色"的文件还原成"红色"
如果修改了文件,如果撤销修改?
- 先用git status查看一下文件名的颜色
- 如果是“红色”:
- 直接使用
git checkout -- {path/to/filename.php}- 把花括号中的名字换成你要还原的文件,需要指定具体路径下的文件
- 如果是“绿色”:
- 绿色的文件,需要先用
git reset还原成红色,再使用git checkout -- 文件名- 如果即没有红色,也没有绿色——已经commit了,咋办?
- 那只能版本回滚了,每个commit都会产生一个commit编号,你可以把这个编号理解为一个版本号,如果当前修改的代码commit了,那么回滚到上一个commit就可以了
- 需要注意的是,回滚到上一个commit之后,当前commit的所有修改过的文件都会被还原,所以版本回滚需谨慎!
如果进行版本回滚?
- 命令很简单
git reset --hard 版本号- 版本号从哪里来?
- 可以在
git log中查看,也可以通过git gui查看
通过git log查看commit 版本号
wenqidongdeMacBook-Pro:kaleoz-api wenqidong$ git log
commit 8b1acd38a0e609d706ff38d74055c3f47099c936 (HEAD -> master, origin/ucp-statistics, origin/master, origin/HEAD, ucp-statistics)
Author: wenqidong <wqd1688@gmail.com>
Date: Tue Jan 29 14:02:19 2019 +0800
新增币种时,接收name_zh参数,返回列表按id倒序
commit b2214d961dd63fb5683fc6a760e0311d2c1c1360
Author: wenqidong <wqd1688@gmail.com>
Date: Mon Jan 28 15:09:11 2019 +0800
部分退款,中间账户变动从买家/订单币中的中间账户变动
commit 98b00e84968c0ee719ec8b61cf15bf8101c98741
Author: wenqidong <wqd1688@gmail.com>
Date: Mon Jan 28 14:08:46 2019 +0800
fix
commit b031e4422e067d64a581b9050328e932803fc863
Author: wenqidong <wqd1688@gmail.com>
Date: Mon Jan 28 11:52:30 2019 +0800
新增币种时自动创建SystemSetting和IntermediateUser
- 项目开发完了可以发布第一个版本了,打个标签(Tag),tag可以取为v1.0表示1.0版本;
git tag -a v1.0 -m "第一个版本发布"
- 默认的标签将打在最新的commit上。
- 查看打了哪些标签使用
git tag
- 查看某个标签的信息用
git show v1.0
- 如果标签打错可以使用以下命令删除:
git tag -d v1.0
- 我想要把v1.0推送到远程,
git push origin v1.0
- 把所有的标签一次推送到远程更爽,
git push origin --tags
- 删除远程的标签,你可以到github上删除,也可以,
- 先删除本地的
git tag -d v1.0
- 删除远程的
git push origin :refs/tags/v1.0

怎样让 git 只更新一个文件?
我们知道git的远端和本地都是一个仓库,当我们使用git pull的时候,会把远端最新的代码拉到本地,并覆盖掉本地代码库和工作拷贝;如果远端代码修改了3个文件,有没有办法只更新一个文件到本地仓库呢? 答案当然是有的。 具体的操作需要用到下面两个命令:
git fetch
git checkout origin/master -- path/to/file
理解 git fetch 的四种用法及与之相关的文件
.git/FETCH_HEAD文件中FETCH_HEAD: 是一个版本链接,记录在本地的一个文件中,指向着目前已经从远程仓库取下来的分支的末端版本。下面是一个测试仓库的FETCH_HEAD
wenqidongdeMBP:doctor wenqidong$ cd .git
wenqidongdeMBP:.git wenqidong$ ls
COMMIT_EDITMSG ORIG_HEAD gitk.cache info packed-refs
FETCH_HEAD config hooks logs refs
HEAD description index objects
wenqidongdeMBP:.git wenqidong$ cat FETCH_HEAD
783cd11f2bcf929a8c50e3532dfb20b967290a5f branch 'feature-wqd' of https://gitee.com/cdinfo/doctor
6fbf9d7fb9a69e8585b18ba375040551f285ce3d not-for-merge branch 'feature-wechat' of https://gitee.com/cdinfo/doctor
783cd11f2bcf929a8c50e3532dfb20b967290a5f not-for-merge branch 'master' of https://gitee.com/cdinfo/doctor
通过git fetch 更新本地仓库的方式
//方法一
$ git fetch origin master //从远程的origin仓库的master分支下载代码到本地的origin master
$ git log -p master.. origin/master//比较本地的仓库和远程参考的区别
$ git merge origin/master//把远程下载下来的代码合并到本地仓库,远程的和本地的合并
//方法二
$ git fetch origin master:temp //从远程的origin仓库的master分支下载到本地并新建一个分支temp
$ git diff temp//比较master分支和temp分支的不同
$ git merge temp//合并temp分支到master分支
$ git branch -d temp//删除temp
关于版本回滚,除了git reset, 还有一个git revert,区分一下什么时候适合用git reset, 什么时候适合用git revert?
1、git reset
没有push,这种情况发生在你的本地代码仓库,可能你add ,commit 以后发现代码有点问题.
首先,Git必须知道当前版本是哪个版本,在Git中,用HEAD表示当前版本,也就是最新的提交commit_id(79f673d631b08907496ce792f429e1f00da25b73),上一个版本就是HEAD^,上上一个版本就是HEAD^^,当然往上100个版本写100个^比较容易数不过来,所以写成HEAD~100。
HEAD指向的版本就是当前版本,因此,Git允许我们在版本的历史之间穿梭,使用命令git reset --hard 79f673d631b08907496ce792f429e1f00da25b73。
穿梭前,用git log可以查看提交历史,以便确定要回退到哪个版本。
要重返未来,用git reflog查看命令历史,以便确定要回到未来的哪个版本。
2、git revert
已经push,对于已经把代码push到线上仓库,你回退本地代码其实也想同时回退线上代码,回滚到某个指定的版本,线上,线下代码保持一致.你要用到下面的命令
git revert用一个新提交来消除一个历史提交所做的任何修改.
revert 之后你的本地代码会回滚到指定的历史版本,这时你再 git push 既可以把线上的代码更新.(这里不会像reset造成冲突的问题)
revert 使用,需要先找到你想回滚版本唯一的commit标识代码,可以用 git log 或者在adgit搭建的web环境历史提交记录里查看.
git revert c011eb3c20ba6fb38cc94fe5a8dda366a3990c613、两者区别
git revert是用一次新的commit来回滚之前的commit,git reset是直接删除指定的commit看似达到的效果是一样的,其实完全不同.
第一:上面我们说的如果你已经push到线上代码库, reset 删除指定commit以后,你git push可能导致一大堆冲突(或git push -f强制推送).但是revert 并不会.
第二:如果在日后现有分支和历史分支需要合并的时候,reset 恢复部分的代码依然会出现在历史分支里.但是revert 方向提交的commit 并不会出现在历史分支里.
第三:reset 是在正常的commit历史中,删除了指定的commit,这时 HEAD 是向后移动了,而 revert 是在正常的commit历史中再commit一次,只不过是反向提交,他的 HEAD 是一直向前的.
git config --global http.proxy 127.0.0.1:1087
git config --local http.proxy 127.0.0.1:1087
(127.0.0.1:1087 这个地址是我翻出去用的代理地址,根据自己的实际修改)
查询是否使用代理:
git config --global http.proxy
git config --local http.proxy
git config --global --unset http.proxy
git config --local --unset http.proxy
PHP项目中,有些公共模块代码,在多个项目中共用 如果每个项目中维护同样的代码块,在更新的时候就很不方便,公共模块更新的时候,需要对每个项目都做一次更新;
当然 PHP中除了用submodule的方式解决公共模块代码共用,还可以通过 composer 的方式实现; 这里只记录 submodule 的方式,以及 submodule 的使用
.gitmodules 文件文件内容
[submodule "Lib"]
path = Lib
url = https://github.com/wqd1688/project_lib.git
branch = main
也可以通过命令创建
git submodule add 仓库地址 目录名称
git submodule add https://github.com/wqd1688/project_lib.git Lib
则会自动创建上面的文件并写入上面的内容;
注意: 自动写入的内容没有 branch 字段,
git 默认的 branch 是 master,
github 现在新建的项目默认主分支已经变成了 main, 所以需要手动指定一下 branch = main
添加好 .gitsubmodules 文件后,执行下面的代码,拉取子模块的代码到本地
git submodule update --remote
本地查看 git 状态时会发现 Lib 目录有更新,直接把 Lib 目录的更新添加,提交就可以, 但是尽量不要直接在 ProjectA中去修改 Lib 中的文件;
其他人拉取 ProjectA 的代码后, Lib 目录可能是空的,需要执行一下
git submodule update
从 ProjectA 中拉取子模块的代码
如果执行
git submodule update --remote
从 子模块 仓库拉取最新代码
# 为新分支创建工作树目录
git worktree add <新路径> <分支名>
# 示例:为 feature/login 分支在 ../myapp-feature 目录创建工作树
git worktree add ../myapp-feature feature/login
# 基于当前 HEAD 创建新分支并工作树
git worktree add ../hotfix -b hotfix/urgent
git worktree list
# 输出示例:
# /path/to/main abc123 [main]
# /path/to/feature def456 [feature/login]
# 删除工作树目录(需先手动删除文件)
git worktree remove <路径>
# 强制删除(即使有未提交更改)
git worktree remove -f <路径>
# 主目录:开发新功能
cd ~/project
# 新建目录用于修复bug而不影响主工作区
git worktree add ~/project-bugfix bugfix/crash
cd ~/project-bugfix
# 修复bug并提交
# 创建待评审分支的工作树
git worktree add ../review-pr-123 pr-123
# 在另一个窗口/IDE中打开,与主分支对比
# 为旧版本维护创建独立工作树
git worktree add ../legacy-v1.0 v1.0-maintenance
# 可长期保持打开,随时修复旧版本问题
--detach)git worktree add --detach <路径> <提交号> 分离HEAD状态git worktree prune 清理记录git worktree remove 完整删除.git 仓库,推送/拉取会相互影响。# 1. 锁定工作树(防止意外删除)
git worktree lock <路径>
# 2. 查看工作树详细信息
git worktree list --verbose
# 3. 一次性添加并切换到新目录
git worktree add -b new-feature ../new-feature && cd ../new-feature
git checkout 的对比优势| 场景 | git checkout |
git worktree |
|---|---|---|
| 临时查看其他分支 | 需暂存/提交当前更改 | 无需任何操作 |
| 并行编译不同分支 | 需反复切换,耗时长 | 同时编译 |
| 长期维护多个版本 | 不方便 | 独立目录,随时访问 |
暂无目录