GIT 常用命令

935 阅读3分钟

GIT的基本操作

创建/克隆仓库

  1. 将远程GIT仓库克隆到本地。
git clone <url>
# 例如 👇
git clone ssh://url/projectName && git config -f .git/config user.name yourName && git config -f .git/config user.email yourName@email.com

git config -f

  1. 创建一个新的项目
mkdir projectName
cd projectName
git init

创建项目目录,并使用 git init 初始化,生成 .git 目录。

将本地修改推送到远程仓库

将远程GIT仓库中的代码检出到工作目录,当我们完成一个阶段的开发之后,需要将变更记录下来并推送到远程。

git add <fileName> / git add .
git commit / git commit -m "commitMessage"
git push origin branchName
  • 进行本地开发
  • git add 将需要的文件进行追踪;
  • git commit 进行提交并编写提交信息;
  • git push 将本次提交推送到远程仓库。

查看本地仓库状态

工作目录下的文件分为已追踪(staged) 和未追踪状态(unstaged)。git status 可以查看到文件的跟踪状态(已缓存、未缓存、未跟踪),也就是 git addgit commit 的操作进度。

$ git status
On branch master
Your branch is behind 'origin/master' by 1 commit, and can be fast-forwarded.
  (use "git pull" to update your local branch)

Changes to be committed:
  (use "git restore --staged <file>..." to unstage)
        modified:   src/test.md

Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git restore <file>..." to discard changes in working directory)
        modified:   src/test.md

Untracked files:
  (use "git add <file>..." to include in what will be committed)
        src/readme.md
  • Changes to be committed: 后边的文件是已追踪状态;
  • Changes not staged for commit: 后边是已追踪文件发生了改变,但还未加入暂存区;
  • Untracked files: 后边的文件为未跟踪状态。 需要使用 git add 可将发生改变的已跟踪文件加入暂存区;也可将未跟踪文件变为已跟踪状态且加入暂存区。

.gitignore 文件中存放想要被GIT忽略的文件路径。

git commit 之后工作目录就和最后一次提交保持一致了,此时 git status 会提示:

On branch master
Your branch is up-to-date with 'origin/master'.
nothing to commit, working directory clean

查看历史提交记录

git log 会按时间先后顺序列出所有的提交,最近的更新排在最上面。

git log <-limit>git log -2 git log --stat -2 展示最近两次提交记录。limit限制提交次数,后面各参数均可使用。

git log -p 或者 git log --patch 会显示每次提交所有差异(diff)。

git log --stat 现实每次提交的下面列出所有被修改过的文件、有多少文件被修改了以及被修改过的文件的哪些行被移除或是添加了。

git log --name-status 显示新增、修改、删除的文件清单。

git log --oneline 一行展示展示一次提交。

撤销操作

1. 重写上次commit

有时候我们提交完了才发现漏掉了几个文件没有添加,或者提交信息写错了。 此时,可以运行带有 --amend 选项的提交命令来重新提交。这个命令会将暂存区中的文件提交(git add 后的文件)。 如果自上次提交以来你还未做任何修改,那么快照会保持不变,而你所修改的只是提交信息。

git commit --amend 进入 vim 编辑提交内容。

image.png

尽量不要撤销/修改已经推送到公共仓库的代码

2. 撤销暂存区的文件

git reset HEAD <file> 可撤销 git add 加入暂存区的文件。

3. 撤销文件的变更

git checkout -- <file> 可撤销工作目录中有变更还未加入暂存区的文件。

4. 后悔了刚刚的操作

git reflog 查看历史操作记录,包含刚刚每一次操作的actionId。

git reset actionID 可以恢复到刚刚的操作。

image.png

3. 合并多条commit记录

参考文档

// -i 的含义是:--interactive, 即弹出交互式的界面让用户编辑完成合并操作
// [startpoint] 指的是合并区间的起点。
// [endpoint] 指的是合并区间的终点,默认是当前分支 HEAD 所指向的 commit。
// (startpoint, endpoint] 不包含startpoint
git rebase -i [startpoint] [endpoint]

Commands 说明

  • p, pick: 保留该 commit。
  • r, reword: 保留该 commit,可以修改 commit 的注释。
  • e, eidt: 保留该 commit,但停下来修改该 commit (不仅仅是注释),可以用来解决 merge 冲突。
  • s, squash: 将该 commit 和 前面一个 commit 合并。
  • f, fixup: 将该 commit 和 前面一个 commit 合并,但不保留该提交的注释信息。
  • x, exec: 执行 shell 命令。
  • d, drop: 丢弃该 commit。

远程仓库

git remote 查看远程仓库仓库服务器

  • -v 会显示需要读写远程仓库使用的 Git 保存的简写与其对应的 URL
  • git remote add <shortname> <url> 添加一个新的远程 Git 仓库,同时指定一个方便使用的简写。
  • git remote show <remote> 查看某个远程仓库,例如 git remote show origin
  • git remote rename 重命名远程仓库的简写名。例如 git remote rename origin origin2
  • git remote remove origin2 或者 git remote rm origin2 移除远程仓库,所有和这个远程仓库相关的远程跟踪分支以及配置信息也会一起被删除。

git clone 命令会自行添加远程仓库。默认配置下远程 Git 仓库中的每一个文件的每一个版本都将被拉取下来

保持代码同步(拉去和推送)

git fetch + git merge / rebase

  1. 获取远程分支提交 git fetch <remote> <branch> 命令只会将远程 commit 数据下载到你的本地仓库的远程分支,并不会自动合并或修改你当前的工作目录。可以使用 git log origin/branch git checkout origin/branch 来查看该远程分支;或者手动将其合入工作目录。

注: origin/master 和 master 不是同一个分支。

  1. 手动合并 git merge origin/master 或者 git rebase origin/master 命令将获取到的远程仓库和本地工作目录进行合并。

git pull

拉去远程 commit 数据之后合并该远程分支到当前分支。

  • git pull origin master = git fetch origin master + git merge origin/master

  • git pull --rebase origin master = git fetch origin master + git rebase origin/master (基于 rebase 的提交)

git push

git push <remote> <branch> 将本地仓库的 commit 数据推送到远程分支。

代码暂存

git stash 可以用于临时存放修改的内容。

应用场景:开发到了一段时间,发现用错了分支,可以将修改的内容暂时存放起来,切换分支之后在将修改的内容拿出来继续开发。

常见命令

  • git stash 将本地修改暂存起来,使工作区和暂存区恢复到为变更之前的状态;
  • git stash save 'message' 暂存时候增加暂存信息;
  • git stash list 查看 stash 列表;
  • git stash show [stash@{1}] 查看暂存的变更内容,stash@{1} 表示那一次存储;
  • git stash apply [stash@{1}] 应用存储,默认应用最近一次存储内容;
  • git stash pop [stash@{1}] 应用某次存储,并将从stash列表中删除,默认最近一次存储;
  • git stash drop [stash@{1}] 丢弃某次存储,并存储从stash列表中删除;
  • git stash clear 清空stash列表。

分支合并

当前分支 master,将 hotfix 分支合并到master分支

git checkout master ---> git pull origin hotfix ---> (解决冲突 ---> git add. ---> git commit -m 'merge') ---> git push origin master

GIT三棵树

本地的GIT仓库包含三棵树,

  1. HEAD 是当前分支引用的指针,总是指向该分支最后一次提交;
  2. Index 缓存区,用来临时存放本地变更;
  3. Working Directory 工作目录,指向本地的实际文件;
  • Working Directory git add Index git commit HEAD
  • HEAD git checkout files Working Directory

image.png

重置/回滚

git reset

7.7 Git 工具 - 重置揭密

git reset 实际上是操作的git三棵树,首先都将 HEAD 向前移动。

  • --soft 移动HEAD。仅仅修改了HEADIndexWorking Directory 没有变,本质上是撤销了 commit 此时工作目录中的状态为已缓存。
  • --mixed 更新索引Index。在移动了HEAD之后更新了Index,此时为撤销 commit 且工作目录为未缓存状态。是git reset的默认模式。
  • --hard 更新工作目录。在更新索引Index后,将工作目录撤销至和Index相同的状态,此时撤销了 commit 并且撤销了本地修改,上次提交的修改将无法恢复。危险❗️危险❗️危险❗️

git revert

git revert commitId 是用一次新的 commit 来回滚之前的提交,中间的提交内容仍然存在。

reset 和 revert 的场景

  • 如果回退分支的代码以后还需要的话用 git revert
  • 如果是用错了分支,该分支上的代码没什么用且不想被其他人看到,适合用git reset

git config

# 设置全局用户名、邮箱
git config --global user.name "John Smith"
git config --global user.email john@example.com

# 添加指令别名
git config --global alias.st status
git config --global alias.ci commit

# 添加指令别名/简化指令
# gpush git gpush master => git push origin HEAD:refs/for/master
git config --global alias.gpush '!f() { : push ; r=$1; [[ -z $r ]] && r=origin; b=$2; t=$(git rev-parse --abbrev-ref HEAD); t=${t#refs/heads/}; [[ -z $b ]]; cmd="git push $r HEAD:refs/for/$b"; echo $cmd; echo; $cmd; }; f'

git checkout 的作用

  • git checkout <branch> 通过移动 HEAD 实现检出分支
  • git checkout <commitId> 基于当前分支的某次提交,检出分支
  • git checkout -b <branch> 创建新分支
  • git checkout <fileUrl> 撤销对文件的更改

git merge 和 git rebase 的区别

参考链接 git merge 和 git rebase 区别

1 -> 2 -> 3 -> 4 -> master
     └─-> 5 -> 6 -> hotfix

1. 提交记录区别

# merge
1 -> 2 -> 3 -> 4 -> 7 -> master/hotfix
     └─-> 5 -> 6 ——─┘
# rebase
1 -> 2 -> 3 -> 4 -> 5' -> 6' -> master/hotfix
  • merge 会把公共分支和你当前的 commit 合并在一起,形成一个新的 commit 提交;
  • rebase 会把你当前分支的 commit 放到公共分支的最后面,整个commit提交成一条直线;
  • merge 可以体现出时间线; rebase 时间比较混乱;

2. 解决冲突区别

本地当前分支为 master 分支

  • merge: 在执行 git merge 后提示冲突,修改冲突后再次执行,执行流程为:
    git add . ---> git commit -m 'xx' ---> git pull origin hotfix ---> 
    解决冲突 ---> git add . ---> git commit -m 'xx' ---> 
    git push origin master
    
  • rebase: hotfix 分支的每次提交都需要和 master 的新代码进行比对,因此需要循环解决冲突,执行流程为:
    git add . ---> git commit -m 'xx' ---> git pull origin hotfix --rebase ---> 
    (`Repeat`解决冲突 ---> git add . --->git rebase --continue )---> 
    git status(只有在working tree clean的状态才能提交) ---> 
    git push origin master –f
    

git rebase 的使用

git rebase -i [startpoint] [endpoint] 可以合并多个 commit ,其中 -i 代表 --interactive 即交互的意思。

[startpoint] [endpoint]则指定了一个编辑区间,如果不指定[endpoint],则该区间的终点默认是当前分支HEAD所指向的commit。

git rebase -i HEAD~2 其中 HEAD~2 表示合并最近两次的提交。

image.png

## git为我们提供的命令说明,上图中每条 commit 之前的 pick 为指令。

pick:保留该commit(缩写:p)

reword:保留该commit,但我需要修改该commit的注释(缩写:r)

edit:保留该commit, 但我要停下来修改该提交(不仅仅修改注释)(缩写:e)

squash:将该commit和前一个commit合并(缩写:s)

fixup:将该commit和前一个commit合并,但我不要保留该提交的注释信息(缩写:f)

exec:执行shell命令(缩写:x)

drop:我要丢弃该commit(缩写:d)

标签 git tag

  • git tag -a tagName <-m "added description release notes"> 创建标签
  • git tag git tag --list/-l 查看tag
  • git checkout tagName 检出指定tag
  • git tag -d tagName 删除本地tag
  • git push origin tagName 将本地tag推送到远程 参考文章