Notes: 本文章用于上手git,并不全面甚至非常简略粗糙,知其然不知其所以然,但希望这些是你将常用的指令。作者本身也是只熟练git基本操作的小白。
安装git的过程不在此说明,网上的教程很多。
首先介绍下git的工作流程,
0. git工作流程:
Workspace:工作区(文件状态modified/unstaged)
add
—>
Index / Stage:暂存区 (文件状态staged)
commit
—>
Repository:仓库区(或本地仓库)(文件状态 committed)
push
—>
Remote:远程仓库
开始
创建仓库:
git init
从现有仓库拷贝项目:
git clone <repo>
分支 branch
主分支通常默认是master分支,提供正式版本。
使用分支意味着你可以把你的工作从开发主线(master)上分离开来,以免影响开发主线。
- 查看分支
查看本地分支
查看远程分支git branch
查看所有分支git branch -r
git branch -a
- 新建分支
可以使用如下指令来新建分支,新建本地分支的名字,最好是远程没有的,以防混乱。
但是更常用的是:git branch <branchname>
新建分支并切换到新建的分支上git checkout -b <branch>
- 切换分支
在本地有修改但是你需要切换到别的分支时,在切换分支前,你需要将你的改动提交,但如果你没有写完并不想提交,可以用git checkout <branch>
git stash
,把所有未提交的修改(包括暂存的和非暂存的)都保存起来。
拉取 pull & fetch
- 拉取特定分支的更新
git fetch <远程主机名> <分支名>
- 更新远程跟踪的所有分支
git fetch origin
- 拉取远程分支的内容更新到本地目录
git pull <远程主机名> <远程分支名>:<本地分支名>
如果当前分支只有一个追踪的分支,可以简写为 git pull
pull的是fetch + merge组成的。
git fetch会将远程仓库变动的提交拉取到本地仓库,而不是本地工作目录,不会自行合并到当前工作目录中,需要手动执行git merge
将这些变动合并到当前的工作目录。
常用操作:
确定自己要基于哪个分支开发,基于这个分支创建新的分支。
切换到基于开发的分支,拉取该分支最新的代码,基于这个分支本地创建并切换到新的分支。
git checkout <branch-name>
git pull
git checkout -b <your-branch-name>
提交代码到远程仓库基本步骤
在你在本地分支上添加修改了代码,需要提交到远程仓库,你需要进行以下步骤。
-
查看仓库状态,显示所有变更的文件
这条指令不是必须做的,但是可以帮助你看项目中本地更改的所有代码的文件。git status
-
添加修改的文件到暂存区
提交多个文件
git add [file1] [file2] ...
提交目录及目录下所有文件
git add [dir]
提交当前目录下所有文件,如果所有修改的文件都需要提交(用
git status
查看),那么可以用下面这一条。git add .
-
提交暂存区到本地仓库
常用指令
git commit -m [message]
其中,[message] 是对提交的代码的备注信息。commit的信息理论上可以随便写,但是还是应该按照公司规定清晰明了的阐明本次代码改动内容。
-
将本地的分支版本上传到远程并合并。
git push <远程主机名> <本地分支名>:<远程分支名>
例如,如下指令表明,将本地的dev分支推送到远程origin主机的dev分支。如果远程dev分支不存在,则会被新建。
git push origin dev
另外,在第一次提交本地分支时,可以通过
git push --set-upstream origin develop
或者git push -u origin develop
,关联本地dev分支的upstream分支。这样之后可以不加任何参数使用直接通过git push
提交代码。可以参考一下这篇文章,Git push与pull的默认行为
- 可以通过
git log
命令查看提交信息。
合并代码: merge操作
例如,合并dev到当前分支
git merge dev
工作上通常是在gitlab上进行mr,在gitlab上提交一个新的merge request,如果代码合并冲突,需要在本地进行rebase操作。
rebase操作
git rebase
命令在另一个分支基础之上重新应用,用于把另一个分支的修改合并到当前分支。
假设你要将远程分支new , merge进dev分支,但是dev分支有新的修改,merge 出现了冲突。
那么你需要做的是:
git checkout dev
git pull
git checkout new
git rebase dev
如果出现冲突那么修改冲突并且将改动git add
到暂存区,并继续
git rebase --continue
在任何时候,可以用–abort参数来终止rebase的操作,并且new分支会回到rebase开始前的状态。
git rebase --abort
最后可以提交 ,(需要force)
git push -f
当多人开发同一分支时,如果别人有提交新的代码,在push之前先fetch, rabase一下,将其他人改动merge进来。
git fetch
git rebase
...解决冲突(如果有的话)
git add <冲突文件>
git rebase –-continue
git push
合并commit
遇到了一个问题,在b分支上rebase a时没有出现conflict,但是发现a分支上的一些codes竟然没有合进来。最后发现是因为在我的b分支上,有一个commit就是把这些codes remove掉(因为之前加在了b分支,又考虑到分支功能的独立,把这些代码删掉,commit到了另一个分支上)。解决办法就是将b分支上的commit合并起来。另外,如果conflict太多,合并commit再rebase 更高效。
操作步骤
git log
查看log信息git rebase -i <commit-SHA>
(这个commit的序号选取需要合并的前一条)- 将想要合并到前一个分支的pick改为squash。
- 更改commit message
我这里写的比较简单,第一次使用可以参考这篇文章。Git」合并多个 Commit
版本回退
在rebase成功后,发现是错误的行为,要怎么撤销rebase操作呢?
恢复本地错误操作,我们可以用git reflog
+ git reset --hard HEAD@{xx}
来回到过去的版本。
reflog指的是Reference logs,也就是参考日志,会显示可引用的历史版本记录。
比如我们想撤销rebase操作,我需要在reflog显示中找到rebase之前的那个版本的HEAD@{n}
,或者commit id的前7位,利用git reset --hard
回到rebase之前的版本。
git reset
的三种方式
工作区 | 暂存区 | 本地仓库(HEAD) | |
---|---|---|---|
--soft | 保留 | 保留 | 回滚 |
--mixed | 保留 | 删除 | 回滚 |
--soft | 删除 | 删除 | 回滚 |
参考:
git reset 的三种模式的使用场景
git reflog命令
git reset命令
一些粗鲁的行为(如果你需要的话)
放弃修改,强制拉取远程代码覆盖本地代码(本地改动将丢失,慎用!)
git fetch --all
git reset --hard origin/<branch-name>
git pull
强制提交到远程仓库
git push --force origin