常见Git命令汇总
文章图片
前言
最近,有朋友私信让我就git 使用
做篇文章分享,分享一下我在日常工作中是如何使用git
的。我当场就收费两包辣条,最后讨价还价,朋友用1.5包辣条骗到了这篇文章,等他欣喜的走了我打算直接分享出来,气死这个吝啬鬼,当然最终还是希望本文对你有所帮助。
基础概念
首先我们简单的概述一下git
,git
有三个分区,分别是:
- 工作区(Working Directory):开发者直接编辑的地方,只要文件发生了更改,在这就会显示出来,包含追踪与未追踪文件。通过
git add
将工作区文件添加到暂存区。 - 暂存区(Stage | Index):数据暂时存放的区域,通过
git commit
将暂存区文件添加到本地版本库。 - 本地版本库(Local Commit History):存放所有已经提交的数据,通过
git push
推送到远程仓库。
文章图片
基础命令 git status 查看工作区状态,如果跟踪的文件有做任何修改,都可以通过该命令来发现。 如:这里通过
git status
就发现在develop
分支上,README.md
文件发生了更改。jere@JereMBP GitTest (develop) $ git status
On branch develop
Changes not staged for commit:
(use "git add ..." to update what will be committed)
(use "git restore ..." to discard changes in working directory)
modified:README.mdno changes added to commit (use "git add" and/or "git commit -a")
git diff 查看具体修改内容,比如在上一步中,我们通过
git status
发现README.md
文件发现了更改,这时我们可以通过git diff
来查看具体的修改内容:jere@JereMBP GitTest (develop) $ git diff README.md
diff --git a/README.md b/README.md
index 7eb4917..3d6d2a4 100644
--- a/README.md
+++ b/README.md
@@ -1,2 +1,5 @@
# GitTest
For git command practice
+
+do something on develop branch
+
jere@JereMBP GitTest (develop) $
另外,你也可以直接使用
git diff
,这样就会显示所有文件的所有修改内容。git checkout 切换分支,比如我在
feature-1
分支上切换到develop
分支上:jere@JereMBP GitTest (feature-1) $ git checkout develop
Switched to branch 'develop'
jere@JereMBP GitTest (develop) $
在当前分支节点上
新建
一个分支并且切换过去
,比如我在 main
分支上创建一个develop
新分支并且切换过去:jere@JereMBP GitTest (main) $ git checkout -b develop
Switched to a new branch 'develop'
jere@JereMBP GitTest (develop) $ git branch
* develop
main
放弃工作区所作的修改,类似
git restore ...
,比如:我现在想放弃README.md
中的修改jere@JereMBP GitTest (develop) $ git status
On branch develop
Changes not staged for commit:
(use "git add ..." to update what will be committed)
(use "git restore ..." to discard changes in working directory)
modified:README.md
modified:dev-file.txtno changes added to commit (use "git add" and/or "git commit -a")
jere@JereMBP GitTest (develop) $ git checkout README.md
Updated 1 path from the index
jere@JereMBP GitTest (develop) $ git status
On branch develop
Changes not staged for commit:
(use "git add ..." to update what will be committed)
(use "git restore ..." to discard changes in working directory)
modified:dev-file.txtno changes added to commit (use "git add" and/or "git commit -a")
jere@JereMBP GitTest (develop) $
另外,如果你想放弃所有工作区中的修改,可以使用
git checkout .
来放弃所有修改。git branch 查看
本地
分支情况:jere@JereMBP GitTest (main) $ git branch
* main
查看
远程仓库
分支情况:jere@JereMBP GitTest (develop) $ git branch --remote
origin/HEAD -> origin/main
origin/main
在当前节点上
创建一个新分支
,比如我在 develop
上创建一个feature-1
新分支:jere@JereMBP GitTest (develop) $ git branch feature-1
jere@JereMBP GitTest (develop) $ git branch
* develop
feature-1
main
另外,关于创建分支还有一些常用的操作可以了解一下,比如:
# 基于某个分支上开出新分支
$ git branch
# 基于某个提交开出新分支
$ git branch commit_hash
# 基于某个tag开出有新分支
$ git branch v1.1
删除分支
- 删除本地分支:
git branch -d
。 - 删除远程分支:
git push -d origin
。
README.md
文件添加到暂存区:jere@JereMBP GitTest (develop) $ git status
On branch develop
Changes not staged for commit:
(use "git add ..." to update what will be committed)
(use "git restore ..." to discard changes in working directory)
modified:README.mdno changes added to commit (use "git add" and/or "git commit -a")
jere@JereMBP GitTest (develop) $ git add README.md
jere@JereMBP GitTest (develop) $ git status
On branch develop
Changes to be committed:
(use "git restore --staged ..." to unstage)
modified:README.mdjere@JereMBP GitTest (develop) $
另外,你也可以通过
git add .
命令,这会将工作区所有的修改内容都添加到暂存区。git commit 将暂存区中的内容保存到本地工作区,如上一步我们已经将
README.md
文件添加到了暂存区,接下来就将它保存到本地工作区:jere@JereMBP GitTest (develop) $ git commit -m "更改README文件"
[develop b18e4f1] 更改README文件
1 file changed, 3 insertions(+)
jere@JereMBP GitTest (develop) $ git status
On branch develop
nothing to commit, working tree clean
jere@JereMBP GitTest (develop) $
另外,你也可以通过
git commit -am
来进行快速操作,其实它就是git add . & git commit -m
的结合体。git push 将本地文件推送到远程仓库中,如:将上一步已经保存到本地的
README.md
文件推送到远程仓库:jere@JereMBP GitTest (develop) $ git push origin develop
Enumerating objects: 5, done.
Counting objects: 100% (5/5), done.
Delta compression using up to 12 threads
Compressing objects: 100% (3/3), done.
Writing objects: 100% (3/3), 371 bytes | 371.00 KiB/s, done.
Total 3 (delta 0), reused 0 (delta 0)
To https://github.com/JereChen11/GitTest.git
1f7fb80..b18e4f1develop -> develop
jere@JereMBP GitTest (develop) $
git fetch 查看远程仓库有没有更新,有更新就下载下来,如果没有更新就没有任何反应,如:这里通过
git fetch
发现远程仓库中main
分支有了新提交,所以将其下载了下来。jere@JereMBP GitTest (develop) $ git fetch
remote: Enumerating objects: 5, done.
remote: Counting objects: 100% (5/5), done.
remote: Compressing objects: 100% (2/2), done.
remote: Total 3 (delta 0), reused 0 (delta 0), pack-reused 0
Unpacking objects: 100% (3/3), done.
From https://github.com/JereChen11/GitTest
30f049e..d6ff31dmain-> origin/main
jere@JereMBP GitTest (develop) $ git fetch
jere@JereMBP GitTest (develop) $
git merge 合并分支,如:在上一步中,我们通过
git fetch
发现远程 mian 分支
有了新提交,所以当前本地main分支
是落后的,所以这时候我们就应该将远程 mian 分支
合并到我们的本地main分支
,来实现两端同步。jere@JereMBP GitTest (develop) $ git checkout main
Switched to branch 'main'
Your branch is behind 'origin/main' by 1 commit, and can be fast-forwarded.
(use "git pull" to update your local branch)
jere@JereMBP GitTest (main) $ git merge origin/main
Updating 30f049e..d6ff31d
Fast-forward
README.md | 2 ++
1 file changed, 2 insertions(+)
jere@JereMBP GitTest (main) $
git pull 拉取远程仓库,如果远程仓库有更新,则会将更新下载下来并合并到当前分支上,相当于
git fetch
与git merge
的结合体。 如:跟上一步同样,这次我们使用git pull
来拉取远程 mian 分支
上的新提交。jere@JereMBP GitTest (main) $ git pull
remote: Enumerating objects: 5, done.
remote: Counting objects: 100% (5/5), done.
remote: Compressing objects: 100% (3/3), done.
remote: Total 3 (delta 1), reused 0 (delta 0), pack-reused 0
Unpacking objects: 100% (3/3), done.
From https://github.com/JereChen11/GitTest
55e808c..4a1a531main-> origin/main
Updating 55e808c..4a1a531
Fast-forward
README.md | 2 ++
1 file changed, 2 insertions(+)
业务场景 除了上面几个基础命令,现在我根据我们平时的业务场景,配合案例再介绍几个指令。
解决冲突 关于冲突,一旦涉及分支合并,且这两个分支有对同一个地方做更改,就会出现冲突。
比如:在上一步中我们将
远程mian分支
拉取了下来,发现他是对README.md
文件做了更改,而我们一开始的时候已经在develop
分支上对README.md
文件相同位置上做了更改,这时候,如果我们尝试将develop
合并到main
分支上时,就会出现冲突。jere@JereMBP GitTest (main) $ git merge develop
Auto-merging README.md
CONFLICT (content): Merge conflict in README.md
Automatic merge failed;
fix conflicts and then commit the result.
jere@JereMBP GitTest (main) $ git status
On branch main
Your branch is up to date with 'origin/main'.You have unmerged paths.
(fix conflicts and run "git commit")
(use "git merge --abort" to abort the merge)Changes to be committed:
new file:dev-file.txtUnmerged paths:
(use "git add ..." to mark resolution)
both modified:README.mdjere@JereMBP GitTest (main) $
正是
README.md
文件发生了冲突,我们需要打开该文件来查看具体冲突内容。# GitTest
For git command practice<<<<<<< HEAD
chagne README file on the main branch //内容1
=======
do something on develop branch //内容2
>>>>>>> develop
冲突的内容会被
<<<<<<<
与>>>>>>>
所包围,中间用=======
隔离开,也就如我所注释的分成了内容1
与内容2
两块。内容1
:是当前所在分支节点的内容,也就是mian
。内容2
:要合并进来分支的内容,也就是develop
。
<<<<<<<
、>>>>>>>
、=======
这些隔离符删除掉,并保存,然后执行git add
、git commit
完成合并。jere@JereMBP GitTest (main) $ vim README.md
jere@JereMBP GitTest (main) $ git status
On branch main
Your branch is up to date with 'origin/main'.You have unmerged paths.
(fix conflicts and run "git commit")
(use "git merge --abort" to abort the merge)Changes to be committed:
new file:dev-file.txtUnmerged paths:
(use "git add ..." to mark resolution)
both modified:README.mdjere@JereMBP GitTest (main) $ git commit -am "解决README冲突"
[main 8e08c23] 解决README冲突
jere@JereMBP GitTest (main) $
组员间同步开发进度 在实际项目中,我们都是多人配合协同开发,会将一些需求进行拆分,然后大家同时开发,开发完成后,各自将自己的代码合并到
develop
分支上。 在这过程中,如果某个组员已经开发完了并且将代码合并到了develop
分支,而你还没开发完,但是这时你想同步这个组员的代码,这时应该怎么做呢?
这里我们就可以使用git rebase
来做到。
git rebase
操作,称之为变基操作,也就是移动你的分支的根节点。举个例子:
feature-1
与feature-2
都是基于develop
同一节点开出来的分支。- 随着开发的进行,
feature-1
先开发完成,并合并到develop
分支。 - 此时
feature-2
利用git rebase origin develop
来同步feature-1
的代码。
jere@JereMBP GitTest (feature-2) $ git rebase origin/develop
First, rewinding head to replay your work on top of it...
Applying: 添加 feature-22.txt 文件
Applying: 修改feature-22.txt
jere@JereMBP GitTest (feature-2) $
这三个状态的节点分支情况如下图所示:
初始状态 | feature-1合并到develop | feature-2同步develop代码 |
---|---|---|
文章图片 |
文章图片 |
文章图片 |
我们可以通过
git rebase -i HEAD~x
来合并(这里 i
的意思为interactive
交互,HEAD~x
代表要合并HEAD
到前x
个历史提交,如: HEAD~2
为历史的前两个提交,HEAD~4
就是历史的前四个提交)。举个例子: 我们在
feature-3分支
上对feature-3.txt
进行了两次提交修改,分别是598cc68 修改feature-3.txt
与8561ef3 再次修改feature-3.txt
,现在我们要将这两个提交进行合并。- 执行
git rebase -i HEAD~2
。 - 这是会自动进入
vim
,显示如下内容:
pick 598cc68 修改feature-3.txt
pick 8561ef3 再次修改feature-3.txt
...省略...
这里我们要合并这两个提交,所以将第二个
pick
更改为s
,如下:pick 598cc68 修改feature-3.txt
s 8561ef3 再次修改feature-3.txt
...省略...
保存退出,将自动打开另外一个
vim
文件,用来修改提交文本信息,如下:# This is a combination of 2 commits.
# This is the 1st commit message:修改feature-3.txt
# This is the commit message #2:再次修改feature-3.txt
# Please enter the commit message for your changes. Lines starting
# with '#' will be ignored, and an empty message aborts the commit.
#
这里我们将其修改为
最终版本,修改feature-3.txt
,保存退出。jere@JereMBP GitTest (feature-3) $ git rebase -i HEAD~2
[detached HEAD 18296c5] 最终版本,修改feature-3.txt
Date: Wed Dec 1 10:21:05 2021 +0800
1 file changed, 2 insertions(+)
Successfully rebased and updated refs/heads/feature-3.
jere@JereMBP GitTest (feature-3) $
- 此时,你本地分支已经完成了合并,你尝试将其推送到仓库中时,会发现被拒绝。通过提示可知,拒绝理由是
our current branch is behind 你当前分支落后远程分支
,这时,我们需要git push origin feature-3 -f
,强制推送,完成合并。
jere@JereMBP GitTest (feature-3) $ git push origin feature-3
To https://github.com/JereChen11/GitTest.git
! [rejected]feature-3 -> feature-3 (non-fast-forward)
error: failed to push some refs to 'https://github.com/JereChen11/GitTest.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.
jere@JereMBP GitTest (feature-3) $ git push origin feature-3 -f
Enumerating objects: 5, done.
Counting objects: 100% (5/5), done.
Delta compression using up to 12 threads
Compressing objects: 100% (2/2), done.
Writing objects: 100% (3/3), 356 bytes | 356.00 KiB/s, done.
Total 3 (delta 0), reused 0 (delta 0)
To https://github.com/JereChen11/GitTest.git
+ 8561ef3...18296c5 feature-3 -> feature-3 (forced update)
这三个状态的节点分支情况如下图所示:
执行 git rebase -i HEAD~2 |
采用squash 合并提交,并修改文本信息 |
强制推送到仓库 |
---|---|---|
文章图片 |
文章图片 |
文章图片 |
pick
改为 s
这一步吗?这里的s
指的是squash
,意思是将该提交挤压合并到上一个提交。 他还有一些其它选项操作可以了解一下:p, pick = 使用提交
r, reword = 使用提交,但是会编辑提交文本信息
e, edit = 使用提交,在修改完成后,可以通过git commit --amend再次进行修改;修改满意后再使用git rebase --continue
s, squash = 使用提交,挤压合并到上一个提交
f, fixup = 类似"squash",会挤压合并到上一个提交,但是会忽略修改提交文本信息这一步。
整理提交的必要性 如果你的分支上存在这样的情况:
提交1:finish login feature
,紧接着后面就是提交2:code review for login feature
。 这样的操作其实很正常,也很合理,你在做好功能后,去做了code review
,但其实我们完全可以将这两个提交合并成一个提交,方便自己以及同事查看你的代码。但
注意:
你要在你自己的分支进行操作。撤销提交 这边撤销提交分为撤销本地提交与撤销远程提交。
撤销本地提交
当你提交了代码到本地,但此时,你想撤回这个提交,重新编辑修改一下。这时你可以通过
git reset
来实现。这个撤销分为是否保留修改。
- 保留修改:
git reset --soft
,你之前所作的更改都在,这也称为最安全的撤销。 - 舍弃修改:
git reset --hard
,你之前所作的更改都会消失,所以要谨慎使用。
feature-4
分支上,你提了一个本地提交第二次修改
,这时你想撤销回来继续修改。jere@JereMBP GitTest (feature-4) $ git reset --soft HEAD~
如果,我直接不要这个
第二次修改
本地提交,则:jere@JereMBP GitTest (feature-4) $ git reset --hard HEAD~
HEAD is now at 16960c7 第一次修改
这三个状态的节点分支情况如下图所示:
初始状态 | git revert --soft |
git revert --hard |
---|---|---|
文章图片 |
文章图片 |
文章图片 |
当你将你的本地提交推送到了远程仓库中,这时,你发现你完全做错了,你想进行回滚操作。
这时你就需要用到
git revert
操作。举个例子: 我在
feature-4
分支上提了两个提交且都推送到了仓库,分别是第一次修改
与第二次修改
,现在我想进行回滚操作,撤销第二次修改
这个提交。jere@JereMBP GitTest (feature-4) $ git revert HEAD
[feature-4 c73e361] Revert "第二次修改"
1 file changed, 1 deletion(-)
执行命令后,会自动打开一个
vim
文件来让你修改提交文本信息,默认在开头加上revert
修饰,保存退出,操作结束。撤销前后这两个状态的节点分支情况如下图所示:
撤销前 | 撤销后 |
---|---|
文章图片 |
文章图片 |
revert xxx
提交,如果你不想要这个提交,不想让人知道你进行了回滚,你可以使用上面介绍的git rebase -i HEAD~x
进行整理合并提交。另外,你也可以通过
git revert
来对指定提交进行回滚,如果遇到冲突就先解决冲突,然后执行git revert --continue
继续。注意
:执行回滚操作需要注意环境,如果别人拉了你的代码,这时你再执行回滚操作,那就不好了。线上出Bug了,紧急修复 讲个故事吧。
经过一段时间的开发,你们的产品终于上线了,版本为
V1.0
,产品上线后你马上投入到了V1.1
版本的需求开发。某天,运营与产品同时过来找你,说刚刚发现线上存在一个很严重的bug
,需要紧急修复一下。你马上投入修复工作,经过紧张的排查与测试,最终你修复了这个问题,准备发版。 而此时,你才注意到,你是在develop
分支上进行的修复工作,而develope
分支已经包含了v1.1
的部分功能,这时,怎么把这个紧急修复提交给到V1.0
呢?可以通过
git cherry-pick
做到,翻译为挑选的意思,将某个提交挑选过来。如:我们现在要将
develop
分支上的d818f10 紧急修复线上bug
这个提交合并到我们main V1.0
上。先切换到main
分支上,然后将d818f10
这个提交挑选过来合并。jere@JereMBP GitTest (develop) $ git co main
Switched to branch 'main'
Your branch is up to date with 'origin/main'.
jere@JereMBP GitTest (main) $ git cherry-pick d818f10
[main 55e808c] 紧急修复线上bug
Date: Wed Dec 1 15:49:48 2021 +0800
1 file changed, 2 insertions(+)
这三个状态的节点分支情况如下图所示:
初始状态 | 在develop 上修复 |
将这个修复提交挑选到main |
---|---|---|
文章图片 |
文章图片 |
文章图片 |
此时我们可以通过
git stash
来暂存我们代码,然后切换到线上环境分支排查问题,解决后,切换回之前分支执行git stash pop
继续开发。如:我现在正在
feature-5
分支上开发新需求,此时我需要暂存所有更改,切换到main
分支排查问题。排查结束,回到feature-5
,将暂存取出,继续开发。jere@JereMBP GitTest (feature-5) $ git status
On branch feature-5
Changes not staged for commit:
(use "git add ..." to update what will be committed)
(use "git restore ..." to discard changes in working directory)
modified:feature-5.txtno changes added to commit (use "git add" and/or "git commit -a")
jere@JereMBP GitTest (feature-5) $ git stash
Saved working directory and index state WIP on feature-5: 9bd4e1f 添加 feature-5.txt
jere@JereMBP GitTest (feature-5) $ git status
On branch feature-5
nothing to commit, working tree clean
jere@JereMBP GitTest (feature-5) $ git stash pop
On branch feature-5
Changes not staged for commit:
(use "git add ..." to update what will be committed)
(use "git restore ..." to discard changes in working directory)
modified:feature-5.txtno changes added to commit (use "git add" and/or "git commit -a")
Dropped refs/stash@{0} (1ec48d00e8d1bd5c0042d88d1209dbb9051815d4)
jere@JereMBP GitTest (feature-5) $
另外,
git stash
还有一些常用操作。# 保存到stash栈中,并加上自定义message修饰
$ git stash save "message"
# 列出stash栈中所有元素
$ git stash list
# 应用stash栈中的第x个元素,pop是应用的同时且从栈中删除,而apply则是只应用不删除
$ git stash apply stash@{x}
# 删除stash栈中的第x个元素
$ git stash drop stash@{x}
上线发版啦 当我们产品开发完成,发现上线时,我们需要打个标签来标注一下,以便下次更好的找它。
这时我们就可以通过
git tag 标签名
来打标签。举个例子:我们的
1.0
版本上线了,所以打个v1.0
。jere@JereMBP GitTest (feature-5) $ git tag v1.0
jere@JereMBP GitTest (feature-5) $ git tag
v1.0
v1.0.1
另外,关于
tag
的一些其它操作有:# 查看所有标签
$ git tag
# 删除指定tag
$ git tag -d 标签名
修改最近提交的文本信息 很多时候,我们提交的时候,可能会输错提交的文本信息,然后想修改一下。
这时,你可以通过
git commit --amend
来修改最近的提交的文本消息。当然,你也可以通过刚刚介绍的撤销本地提交做到,这边就不再次展示了。
git config 一些配置 通过
git config --list
来查看你的git配置信息
。配置别名 每次输入我们都需要输入完整的
checkout
、commit
,很麻烦,我们可以通过设置别名来实现。$ git config --global alias.co checkout
$ git config --global alias.br branch
$ git config --global alias.ci commit
$ git config --global alias.st status
设置完成后,你在通过
git config --list
查看配置,就会发现:alias.co=checkout
alias.br=branch
alias.ci=commit
alias.st=status
之后你就可以通过
git co
、git st
来切换分支、查看状态了..配置代理 因为一些特殊网络原因,我们很多时候上
github
很不稳定,有时候我们推送一些代码会403
失败。这时我们就可以通过设置代理来解决。比如:我们设置一个本地代理。
git config --global http.proxy http://127.0.0.1:1080
git config --global https.proxy https://127.0.0.1:1080
git config --global http.proxy 'socks5://127.0.0.1:1080'
git config --global https.proxy 'socks5://127.0.0.1:1080'
设置完成后,你再通过
git config --list
查看配置,就会发现:http.proxy=http://127.0.0.1:1080
https.proxy=https://127.0.0.1:1080
设置代理成功后,某天,你想取消该代理,这时我们可以通过
unset
来取消代理设置。git config --global --unset http.proxy
git config --global --unset https.proxy
结尾: OK,文章到此也就结束啦。
建议对
git
命令还不太熟练的同学多上手试试,遇到问题不要慌,注意看它给的提示,相信很快就能掌握啦。其实分享文章的最大目的正是等待着有人指出我的错误,如果你发现哪里有错误,请毫无保留的指出即可,虚心请教。 另外,如果你觉得文章不错,对你有所帮助,请给我点个赞,就当鼓励,谢谢 ~Peace~!【常见Git命令汇总】转自:Jere_Chen
推荐阅读
- Linux命令工作实践|001 研发同学必学哪些 Linux 命令()
- Linux|Linux 常用高频基础命令
- kubenetes-常用命令
- [笨叔点滴5] git rebase和git merge究竟有啥区别()
- Linux之last命令
- 融合通信常见问题3月刊 | 云信小课堂
- redis复制
- 常用网络命令总结
- vue|前端学习笔记 webpack及命令文件结构
- Other|GitLab 配置 SSH 密钥(详细流程)