GIT的基本操作
创建/克隆仓库
- 将远程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
复制代码
- 创建一个新的项目
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 add
和 git 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 编辑提交内容。
尽量不要撤销/修改已经推送到公共仓库的代码
2. 撤销暂存区的文件
git reset HEAD <file>
可撤销 git add
加入暂存区的文件。
3. 撤销文件的变更
git checkout -- <file>
可撤销工作目录中有变更还未加入暂存区的文件。
远程仓库
git remote
查看远程仓库仓库服务器
-v
会显示需要读写远程仓库使用的 Git 保存的简写与其对应的 URLgit 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
- 获取远程分支提交
git fetch <remote> <branch>
命令只会将远程 commit 数据下载到你的本地仓库的远程分支,并不会自动合并或修改你当前的工作目录。可以使用 git log origin/branch
git checkout origin/branch
来查看该远程分支;或者手动将其合入工作目录。
注: origin/master 和 master 不是同一个分支。
- 手动合并
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 数据推送到远程分支。
分支合并
当前分支 master,将 hotfix 分支合并到master分支
git checkout master ---> git pull origin hotfix ---> (解决冲突 ---> git add. ---> git commit -m 'merge') ---> git push origin master
GIT三棵树
本地的GIT仓库包含三棵树,
- HEAD 是当前分支引用的指针,总是指向该分支最后一次提交;
- Index 缓存区,用来临时存放本地变更;
- Working Directory 工作目录,指向本地的实际文件;
- Working Directory
git add
Indexgit commit
HEAD- HEAD
git checkout files
Working Directory
重置/回滚
git reset
git reset
实际上是操作的git三棵树,首先都将 HEAD
向前移动。
--soft
移动HEAD。仅仅修改了HEAD
,Index
和Working Directory
没有变,本质上是撤销了commit
此时工作目录中的状态为已缓存。--mixed
更新索引Index。在移动了HEAD之后更新了Index,此时为撤销commit
且工作目录为未缓存状态。--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
表示合并最近两次的提交。
## 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
查看taggit checkout tagName
检出指定taggit tag -d tagName
删除本地taggit push origin tagName
将本地tag推送到远程