git实用指南

这里直接贴一个参考合集,该合集内容较多,这里只提取关键部分

从零开始手把手学习 Git 神器_慧天城寻的博客-CSDN博客

基础操作

初始化与克隆

1
2
3
4
5
# 在当前目录初始化一个新的Git仓库
git init

# 从远程仓库克隆项目到本地
git clone <远程仓库地址>

关联远程仓库

1
2
# 添加远程主机名(通常命名为origin)及对应URL
git remote add origin <远程仓库地址>

创建分支

1
2
3
4
# 1. 创建分支
git branch firstBranch
git checkout -b firstBranch # 创建并切换到分支
git switch -c firstBranch # 创建并切换到分支(Git更新后的推荐命令)

拉取远端指定分支

1
2
3
4
5
6
7
8
9
#查看远程分支
git branch -r
#创建本地分支并关联
git checkout -b 本地分支 origin/远程分支

#已有本地分支创建关联
git branch --set-upstream-to origin/远程分支名 本地分支名
#拉取
git pull

查看当前修改了哪些内容

git status 命令用于查看在你上次提交之后是否有对文件进行再次修改。

1
2
git status
git diff [file]

git diff [file] 命令用来显示暂存区和工作区文件的差异,显示的格式正是Unix通用的diff格式。也可以使用 git diff HEAD -- [file] 命令来查看版本库和工作区文件的区别。

注意:如果是新增的文件,git diff不会显示,但在git status会有

删除文件

1
2
3
4
5
# 从版本库和工作区中删除文件,等同于手动删除后再执行git add
git rm [file]

# 仅从版本库中删除,保留工作区中的文件(常用于误add但不想追踪的文件)
git rm --cached [file]

撤销修改

1
2
3
4
5
6
7
8
9
10
11
12
# 将文件回退到上一次add或者commit的状态(工作区修改全部丢弃)
git checkout -- [file]
# 或者使用更现代的命令
git restore [file]

# 文件已经add了(撤销暂存区的修改,保留工作区修改)
git reset --mixed HEAD [file]
# 或者使用更现代的命令
git restore --staged [file]

# 文件已经commit(版本回退)
git reset --hard HEAD^ [file]

版本回退

将工作区文件回到上一次提交时的状态,也即从版本库重新拉取文件到工作区。

1
2
3
4
5
6
7
8
# 将文件回到上一次提交状态(add和commit都算)
git checkout -- [file]

# 回退到指定版本号
git reset --hard [版本号]

# 本地回退之后强制推送到远端(谨慎使用,会覆盖远端记录)
git push --force

执行 git reset 命令用于回退版本,可以指定退回某一次提交的版本。要解释一下回退本质是要将版本库中的内容进行回退,工作区或暂存区是否回退由命令参数决定:

git reset 命令语法格式为:git reset [–soft | –mixed | –hard] [HEAD]

–mixed 为默认选项,使用时可以不用带该参数。该参数将暂存区的内容退回为指定提交版本内容,工作区文件保持不变。
–soft 参数对于工作区和暂存区的内容都不变,只是将版本库回退到某个指定版本。
–hard 参数将暂存区与工作区都退回到指定版本。切记工作区有未提交的代码时不要用这个命令,因为工作区会回滚,你没有提交的代码就再也找不回了,所以使用该参数前一定要慎重。

HEAD 说明:
可直接写成 commit id,表示指定退回的版本
HEAD 表示当前版本
HEAD^ 表示上一个版本
HEAD^^ 表示上上一个版本
以此类推…

也可以使用波浪线数字表示:
HEAD0 表示当前版本
HEAD
1 上一个版本
HEAD~2 上上一个版本
以此类推…

提交到暂存区

1
git add .

提交到仓库

1
git commit -m "message"

修改上一次提交

如果提交后发现漏掉了某个文件,或者提交信息写错了,且尚未推送到远程,可以使用以下命令将本次修改合并到上一次提交中:

1
2
3
4
# 修改文件后
git add .
# 将暂存区内容与上一次提交合并,并替换提交信息
git commit --amend -m "新的提交信息"

获取与拉取的区别

1
2
3
4
5
# 仅获取远程更新到本地,不自动合并到当前分支
git fetch origin

# 获取远程更新,并自动合并到当前分支(等同于 git fetch + git merge)
git pull origin

git log和git reflog

1
2
3
4
5
6
7
git log
git log --pretty=oneline
git log --pretty=oneline --abbrev-commit -<number>
git log --pretty=format:"%h - %an %cr : %s" --graph -<number>

# 查看所有操作记录(包括被回退的提交),用于找回丢失的版本号
git reflog

打标签

1
2
3
4
5
6
7
8
# 在当前提交打标签
git tag v1.0
# 在指定提交打标签
git tag v0.9 [commit_id]
# 推送标签到远程
git push origin v1.0
# 推送所有本地标签
git push origin --tags

分支管理

查看,新建,切换分支

1
2
3
4
5
6
7
8
9
10
git branch
git branch -r

git branch [new_branch]

git checkout -b [new_branch]
git switch -c [new_branch]

git checkout [branch_name]
git switch [branch_name]

合并分支

git merge 命令用于合并指定分支到当前分支。

Fast-forward 代表快进模式,也就是直接把 master 指向 dev 的当前提交,所以合并速度非常快。

当然,也不是每次合并都能 Fast-forward,我们后面会讲其他方式的合并。

Git 支持我们强制禁用Fast forward模式,那么就会在 merge 时生成一个新的commit,这样,从分支历史上就可以看出分支信息。

下面我们实战一下 --no-ff 方式的 git merge

请注意 --no-ff 参数,表示禁用 Fast forward 模式。禁用 Fast forward 模式后合并会创建一个新的 commit,所以加上 -m 参数,把描述写进去。

1
2
git merge [branch_name]
git merge --no-ff -m "message" [branch_name]

注意:如果你先在master上新建了一个分支branch1,然后在branch1上进行修改,这个时候你想丢弃修改,试图使用git merge master将master分支合并到当前分支,结果发现毫无变化。
注意merge并不是将master分支的内容复制到当前分支,只是把master上的提交合入当前分支的提交树,这两个分支上的所有提交的历史都是存在的。由于branch1是从master分支创建的,且之后master没有改变,那么执行merge不会有任何变化。

删除分支

合并完成后,dev 分支对于我们来说就没用了,那么 dev 分支就可以被删除掉。使用 git branch -d 命令,注意如果当前正处于某分支下,就不能删除当前分支,需要切换到其他分支进行删除。如果要强制删除未合并的分支,使用大写字母 D

1
2
git branch -d [branch_name]
git branch -D [branch_name]

保存工作区状态

如果需要暂时保存工作区内容,切换分支可以如下操作:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# 暂时存储工作区内容
git stash

# 显示stash内容
git stash list

# 恢复之前工作区内容并删除stash记录
git stash pop

# 恢复工作区内容但不删除stash记录
git stash apply

# 删除指定的stash记录
git stash drop stash@{0}

恢复现场也可以采用 git stash apply 恢复,但是恢复后,stash内容并不删除,你需要用 git stash drop 来删除;你也可以进行多次 stash,恢复的时候,先用 git stash list 查看,然后恢复指定的 stash,用命令 git stash apply stash@{0}

正确的合并方式

最好在自己的分支上合并下 master,再让 master 去合并 dev,这样做的目的是有冲突可以在本地分支解决并进行测试,而不影响 master

远程仓库

1
2
git remote
git remote -v
1
2
3
4
git push <远程主机名> <本地分支名>:<远程分支名>

# 如果本地分支名与远程分支名相同,则可以省略冒号:
git push <远程主机名> <本地分支名>
1
2
3
4
git pull <远程主机名> <远程分支名>:<本地分支名>

# 如果远程分支是与当前分支合并,则冒号后面的部分可以省略。
git pull <远程主机名> <远程分支名>

远端拉取指定分支到本地

1
2
3
4
5
6
7
8
9
# 查看远端分支
git ls-remote --heads origin

# 添加远端分支到本地
git branch --track branch1 origin/branch1

# 拉取并合并分支
git checkout branch1
git pull origin branch1

设置代理

1
2
3
4
5
6
7
8
9
10
11
# 查看
git config --global --get http.proxy
git config --global --get https.proxy

# 设置
git config --global http.proxy http://127.0.0.1:7890
git config --global https.proxy http://127.0.0.1:7890

# 取消代理设置
git config --global --unset http.proxy
git config --global --unset https.proxy

常见实战场景与命令组合

场景一:日常代码提交与同步

这是最基础的工作流,适用于个人在单一分支上开发。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# 1. 查看当前修改了什么
git status
git diff

# 2. 将所有修改加入暂存区
git add .

# 3. 提交到本地仓库
git commit -m "feat: 完成登录功能"

# 4. 在推送前,拉取远程仓库的最新代码(防止有别人推送了新代码导致冲突)
git pull origin main

# 5. 推送到远程仓库
git push origin main

场景二:新功能分支开发与合并

适用于团队协作,在独立的分支上开发新功能,完成后再合并到主分支。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
# 1. 切换到主分支并拉取最新代码
git checkout main
git pull origin main

# 2. 创建并切换到新功能分支
git checkout -b feature/login-module

# 3. 在新分支上进行开发、提交(可多次add和commit)
git add .
git commit -m "feat: 添加登录页面"

# 4. 切换回主分支
git checkout main

# 5. 拉取最新的主分支代码(防止期间主分支有更新)
git pull origin main

# 6. 将新功能分支合并到主分支
git merge feature/login-module

# 7. 推送主分支到远程
git push origin main

# 8. 删除本地已合并的分支(可选)
git branch -d feature/login-module

场景三:将多次提交合并为一次(变基)

在开发过程中可能会产生很多零碎的提交记录(如fix typo、update style等),在推送到远程或发起合并请求前,希望将这几次提交合并为一次,保持提交历史整洁。这里使用交互式变基。
假设当前分支有3次新提交,想要合并它们:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
# 1. 查看提交记录,确认要合并的次数
git log --oneline
# 输出:
# a1b2c3d 第三次提交
# e4f5g6h 第二次提交
# i7j8k9l 第一次提交
# ...

# 2. 启动交互式变基,合并最近3次提交
git rebase -i HEAD~3

# 3. 此时会打开编辑器,显示如下内容:
# pick i7j8k9l 第一次提交
# pick e4f5g6h 第二次提交
# pick a1b2c3d 第三次提交

# 4. 将除了第一行的 "pick" 改为 "squash"(或简写为 s),表示将该提交压合并到前一个提交中:
# pick i7j8k9l 第一次提交
# squash e4f5g6h 第二次提交
# squash a1b2c3d 第三次提交

# 5. 保存并退出编辑器。接着会打开第二个编辑器,让你编辑合并后的最终提交信息,修改后保存退出。

# 6. 如果之前已经将这3次提交推送到了远程,现在本地提交历史已经改变,需要强制推送(务必确认没有其他人基于该分支开发):
git push --force origin <当前分支名>

场景四:解决合并冲突

当两个分支修改了同一个文件的同一位置时,合并会产生冲突,Git会提示冲突并暂停合并。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# 1. 执行合并操作时发现冲突
git merge feature-branch
# 提示:CONFLICT (content): Merge conflict in xxx.js
# Automatic merge failed; fix conflicts and then commit the result.

# 2. 使用状态命令查看哪些文件有冲突
git status

# 3. 打开冲突文件,手动修改。文件中会有如下标记:
# <<<<<<< HEAD
# 这是当前分支的代码
# =======
# 这是被合并分支的代码
# >>>>>>> feature-branch
# 根据实际需求保留正确的代码,删除 <<<<<<< 、 ======= 、 >>>>>>> 这些标记。

# 4. 修改完成后,将解决冲突的文件加入暂存区
git add .

# 5. 提交这次合并(此时不需要带 -m 参数也可以,Git会自动生成合并提交信息,也可以自定义)
git commit -m "fix: 解决登录模块合并冲突"