前言:
Git作为分布式版本控制系统,是我们工作和开源代码平台项目管理最火的工具之一,基本上是每个入职的同学都要熟知和学习的。由于我以前的公司都是用的SVN,有时也会用的github客户端,最近抽空来学习下Git的指令使用,听说这样的操作比较骚哦
一、Git下载
- Git下载地址:https://git-scm.com/downloads
- 这边我在win10安装,桌面右键打开Bash输入界面,在本地创建我们的测试仓库
cd ..
//进入d盘创建我们的测试仓库
cd d:
mkdir git_repository
cd git_repository/
//pwd打印当前目录地址
$ pwd
/d/git_repository
-
通过git init初始化,ls -ah显示隐藏目录即可看到相应的文件,我们的git仓库便创建好了
二、Gti文件状态生命周期和文件流向
1. Git文件状态通过git status查询,分别是Untracked,Unmodified,Modified,staged,对应关系如下图
下面我们来验证,我这边测试是我github上的一个demo,通过一个简单的txt文档的创建修改和提交,来演示这四种生命状态:
-
创建新的文档,识别味Untracked状态
-
下面add a.txt,状态编码Umodified,显示我们可以直接commit,add之后修改文档,显示味Modified状态
-
commit 文件,再次查看,状态回到了Unmodified,再次修改又回出现上一条的状态结果
三、Git关联&推送&回退&删除&克隆操作以github为例
进入我的github个人账号,new a Repositories,我的项目名称:NativeRegisterDemo
-
关联并上传项目
//进入项目工程目录,初始化工程目录为git仓库 echo "# NativeRegisterDemo" >> README.md git init git add README.md git add . //此处为添加工程所有文件到git暂存区 git commit -m "first commit" git remote add origin https://github.com/fmer/NativeRegisterDemo.git //关联一个远程仓库 git push -u origin master //要求输入Github的账号密码,推送到主线
-
**修改提交: **README.md
git add README.md git commit -m "update my readme.md" git push -u origin master
-
查看提交日志:能看到我们的2次提交记录,git log --pretty=oneline 命令显示从最近到最远的提交日志,后缀"--pretty=oneline"为过滤信息,其中那一串
-
回退我们的上一个版本,回退后我们再看log历史就只有一条提交记录了
git reset --hard HEAD~1 //HEAD代表当前版本,0-100代表往后的版本,0为当前,1为上一个版本 cat README.md//果然已经回退到上个 first commit版本
-
参数含义:通过git reset --help查看
git reset [<mode>] [<commit>] This form resets the current branch head to <commit> and possibly updates the index (resetting it to the tree of <commit>) and the working tree depending on <mode>. If <mode> is omitted, defaults to "--mixed". The <mode> must be one of the following: --soft Does not touch the index file or the working tree at all (but resets the head to <commit>, just like all modes do). This leaves all your changed files "Changes to be committed", as git status would put it. --mixed Resets the index but not the working tree (i.e., the changed files are preserved but not marked for commit) and reports what has not been updated. This is the default action. If -N is specified, removed paths are marked as intent-to-add (see git-add(1)). --hard Resets the index and working tree. Any changes to tracked files in the working tree since <commit> are discarded. --merge Resets the index and updates the files in the working tree that are different between <commit> and HEAD, but keeps those which are different between the index and working tree (i.e. which have changes which have not been added). If a file that is different between <commit> and the index has unstaged changes, reset is aborted. In other words, --merge does something like a git read-tree -u -m <commit>, but carries forward unmerged index entries. --keep Resets index entries and updates files in the working tree that are different between <commit> and HEAD. If a file that is different between <commit> and HEAD has local changes, reset is aborted.
-
-
如果我们想再回到刚才"update my readme.txt"的版本,也就是在当前的版本上前进到未来版本,我们需要通过git reflog 查看操作记录,然后再通过reset 指定历史版本的commit id即可推进到我们最新的版本
git reflog git reset --hard 4cabf0bd3fb24768bc108ef5bc81fa581d115fee
撤销修改:git checkout -- file,将文件撤回到上一个commit或者add状态或者 通过git reset HEAD file将暂存区的修改撤回到工作区
删除文件,rm a.txt 删除本地 git rm a.txt 本地库删除 然后commit
-
从远程库克隆,上面说了推送本地项目到我们的github仓库,现在介绍如何克隆项目,我们还是这个项目,新建一个文件夹test
git clone git@github.com:fmer/NativeRegisterDemo.git
-
ssh的使用:以上一条clone为例,为了避免https麻烦的密码输入,我们可以选择使用ssh的方式,需要在本地和远程仓库关联一个ssh key,否则会被权限拒绝,如图操作。
- 本地生成ssh的rsa密钥:ssh-keygen -t rsa -C fmer_lin@foxmail.com,会在本地生成一个.ssh文件夹,里面包含文件id_rsa和id_rsa.pub
- 关联远程库,以github为例:在https://github.com/settings/keys页面新建一个SSH key,将本地id_rsa.pub内容复制进去,具体操作如下图:
四、Git项目分支创建管理
创建分支:git checkout -b branch_1 "git checkout -b "---创建并选择分支
查看分支:git branch
-
选择分支:git checkout master
-
合并分支:git merge branch_1 ,可以通过指定参数--no-ff,如git merge --no-ff branch_1 禁用fast forward模式,默认味分支改动模式,这样方便知道改动内容
-
合并冲突处理:再次在brach_1的a.txt添加内容再合并,会发现出现合并冲突,下图可以看到分别在主线和支线提交相同文档造成的冲突问题,合并后可通过指令查看:git log --graph --pretty=oneline --abbrev-commit
LP@lp MINGW64 /d/ipcdemo/test/NativeRegisterDemo (master) $ git checkout branch_1 M a.txt Switched to branch 'branch_1' LP@lp MINGW64 /d/ipcdemo/test/NativeRegisterDemo (branch_1) $ echo modify_branch>merge.txt LP@lp MINGW64 /d/ipcdemo/test/NativeRegisterDemo (branch_1) $ git add merge.txt warning: LF will be replaced by CRLF in merge.txt. The file will have its original line endings in your working directory. LP@lp MINGW64 /d/ipcdemo/test/NativeRegisterDemo (branch_1) $ git commit -m "modify from branch_1" [branch_1 cc45372] modify from branch_1 warning: LF will be replaced by CRLF in merge.txt. The file will have its original line endings in your working directory. 1 file changed, 1 insertion(+) create mode 100644 merge.txt LP@lp MINGW64 /d/ipcdemo/test/NativeRegisterDemo (branch_1) $ git checkout master M a.txt Switched to branch 'master' Your branch is ahead of 'origin/master' by 1 commit. (use "git push" to publish your local commits) LP@lp MINGW64 /d/ipcdemo/test/NativeRegisterDemo (master) $ echo modify_master>>merge.txt LP@lp MINGW64 /d/ipcdemo/test/NativeRegisterDemo (master) $ git add merge.txt warning: LF will be replaced by CRLF in merge.txt. The file will have its original line endings in your working directory. LP@lp MINGW64 /d/ipcdemo/test/NativeRegisterDemo (master) $ git commit -m "modify from master" [master 71e1e12] modify from master warning: LF will be replaced by CRLF in merge.txt. The file will have its original line endings in your working directory. 1 file changed, 1 insertion(+) create mode 100644 merge.txt LP@lp MINGW64 /d/ipcdemo/test/NativeRegisterDemo (master) $ git merge branch_1 Auto-merging merge.txt CONFLICT (add/add): Merge conflict in merge.txt Automatic merge failed; fix conflicts and then commit the result. LP@lp MINGW64 /d/ipcdemo/test/NativeRegisterDemo (master|MERGING) $ cat merge.txt <<<<<<< HEAD modify_master ======= modify_branch >>>>>>> branch_1 LP@lp MINGW64 /d/ipcdemo/test/NativeRegisterDemo (master) $ git log --graph --pretty=oneline --abbrev-commit * 71d1f1a fix my abort |\ | * cc45372 modify from branch_1 * | 71e1e12 modify from master |/ * 0c2dc77 add from branch_1 tes * ab377d0 remove a.txt * f7b229e a.txt * 4cabf0b update my readme.md * bd26f65 first commit
删除分支:git branch -d brach_1
-
分支状态保管:git stash,保存当前的分支状态即工作内容,便地切换到其他分支工作,它的保存历史作为一个list存储,可以保存多次
- git stash list查看列表
- git stash apply 恢复,通过git stash apply stash@{x} x为保管列表id,指定恢复
- git stash drop 取第一个恢复并删除
- git stash drop 删除
关联本地分支和远程分支:git branch --set-upstream-to <branch-name> origin/<branch-name>
查看远程库信息:git remote -v
添加标签: git tag v1.0.0 在当前的commit上打标签,或者在后面指定commit id指定打在相应的commit记录上如:git tag v1.0.1 fsfag143
删除本地git仓库:find . -name ".git" | xargs rm -Rf 在线:rm -rf https://github.com/NeroSolomon/VLearning.git
四、在具体项目协作中如何整合版本
- 在与同事协作开发时,如果出现同事事先提交了代码,我们再去push就会出现推送失败的情况,这是我们需要先抓取远程仓库代码,在本地合并后再提交
- 要注意的时,抓取远程分支需要关联本地和远程分支,参考上节第8
- 在抓取代码再提交中,学会使用rebase去把本地的分支提交记录归档成一条主线
- 在提交代码或者版本时,打上标签,这样能让大家简单明了的浏览history,上节第10
好了,一些常用的指令操作已经学完了,快去练习一下吧。git的操作远远不止这些,在开发过程中可以参考他的中文指导文档:
https://git-scm.com/book/zh/v1/%E8%B5%B7%E6%AD%A5