本文是笔者学习廖雪峰的Git教程记录的笔记,算是对其内容的精简,仅供查询和回顾之用。若有疏漏,还请查看其原文。
Git进行版本控制,管理的是修改而非文件。分清楚工作区,版本库,暂存区(stage)就能很好地理解其工作原理。
工作区(Working Directory):顾名思义是工作的地方,对文件的创建,修改,添加,删除等都会对其造成影响。比方说我创建的一个项目工程就是一个工作区。
版本库(Repository):工作区中有一个隐藏的目录.git,不算工作区而是Git版本库。
Git版本库最终的就是stage(或者叫index)的暂存区,还有Git默认创建的master分支,以及指向master分支的HEAD指针。
文件的增删变更直接作用在工作区,第一步,变更后add,就添加到了版本库的暂存区。
第二步,git commit提交更改,就是将暂存区的所有内容提交到当前分支。
简单的理解就是,需要提交的文件修改都放在暂存区,然后一次性提交暂存区中的内容到到当前分支。
git checkout -- filenname
git add
添加修改到了暂存区,想直接丢弃工作区的修改,分两步,第一步,使用命令git reset HEAD filename
,就回到了场景1;第二步按照场景1来操作。git commit
提交了不合适的修改到版本库中,想要撤销本次提交,就执行版本退回命令,git reset --hard commid_id
进行时光穿梭。穿梭前可以使用git log
查看历史版本;当还需要重返未来的时候,使用git reflog
查看历史命令。使用rm filename
来在工作区删除文件,现在工作区和版本库就不一致了。
git rm filename
命令,然后git commit
git checkout -- filename
,使用版本库中的版本替换到工作区的版本。git checkout -b branch_name
.相当于两句指令:git branch branch_name
, 随后git checkout branch_name
ps: 关于Vim重命名文件,在退出之前输入:sav new_file_name
即可,会保存一个相同内容的副本,而不是在当前修改文件中修改,要想这样需要安装特定的插件。
git branch
git branch
git checkout
git checkout -b
git merge
git branch -d
新建分支在上面修改后,add, commit,然后切换到要汇入的分支上,假如此时在当前分支上也做了修改,执行git merge
时发现无法合并,使用git status
查看冲突位置,然后修改冲突(就是文件中标注的位置,通常就是同一行内容不一致导致的),修改完毕后重新add,commit,以及merge就行了。
可以使用git log --graph <--abbrev-comit> 查看分支合并情况图
。
通常合并分支使用的都是Fast forward
模式,在合并的时候加上--no-ff
参数就可以采用普通模式合并,历史记录中会有分支的信息,而Fast forward
在合并后删除分支日志历史中就没有关于此分支的记录,也就看不出来曾经做过合并。
场景:当手头正在多某项工作,突然接到任务需要马上处理,手头的工作不得不停下,但是还没有完善到能够提交的程度。该怎么办?
相当于打断点,保存现场,使用git stach
保存当前的工作。然后去处理临时或者紧急的任务(比如说修复某个bug)。当临时或者紧急任务处理完毕后,返回来恢复现场继续原来的工作。
恢复现场使用,git stash list
查看有哪些存档,然后使用git stash apply
来恢复,参数是可选的用于多次stash之后选择要恢复的那个。这种方式恢复后stash的内容不删除,需要输入git stash drop
来删除。
另一种方式能够恢复的同时删除stash,即使用git stash pop
。
场景:导师给了个新需求要做,做完了却悲催地听说不需要了,现在要删除这个分支。git brach -d
,会提示The branch '
。
所以git branch -D
就是强制删除未曾合并过的分支的命令。
场景1:在本地创建了一个分支,但是远程没有,commit之后希望push到远程比方说Github上,但是不是master分支,而是一个目前还没有创建的分支上。使用git push -u origin
,这样就在远程创建了和local_branch_name
同名分支。
场景2:远端已经存在和本地同名或者不同名的分支,希望这时将本地的分支推到远端上,git push
场景3:当有多人同时提交到一个分支,自己的提交和他人的有冲突,这时按照提交的提示来做,一般会提示git pull ...
,将远程的提交pul下来。pull下来后再次提交,若发现push有冲突,则需要手动解决冲突,解决方法和上文的冲突解决一致。解决后再进行push即可。
场景4:远程已经存在某个分支,想在本地创建一个分支和远程的分支对应起来。使用git checkout -b local_branch_name origin/remote_branch_name
场景5:远程已经存在某个分支,本地同时存在某个分支,现在要把两个关联起来,使用git branch --set-upstream-to=origin/remote_branch_name local_branch_name
,制定本地分支和远程分支的关联。这样就能解决某些时候pull失败的问题,比如no tracking information
。
git rebase
命令实现。场景1:某个工作已经进行了多次的编辑和提交。过了一阵子,导师或者其他人说,请把之前的某次提交打包一下。这时选择查找commit_id
显得就不是很方便。tag
就相当于是对于commit的起的别名,使用git tag
默认为最近的一次提交打上标签,在产看log的时候,就会出现相应的标签提示。使用git show tag_name
来查看tag_name
对应的那次提交。
场景2:之前的提交忘记打标签,现在需要对历史中某个版本打上标签。使用git tag tag_name commit_id
。使用git tag
查看所有标签。
场景3:创建某个标签的同时,还提供一些说明信息。使用git tag -a tag_name -m "balala enengy... commit_id
。使用git show tag_name
就能查看到相应说明文字。
git tag -d tag_name
git push origin tag_name
git push origin --tags
git push origin :refs/tags/tag_name
,然后去远程查看标签是否被删除。除了配置user.name
, user.email
之外还可以配置一些东西。
git config --global color.ui true
,使文件名也被不同的颜色标注。(我使用git bash本身就是有颜色的)。这个功能非常有必要,特别是在一些项目中有比较大或者涉及敏感信息的文件时(比如密码,很大很大的数据集等)。编写.gitignore
文件来屏蔽某些类型的文件。文件每行表示一个屏蔽规则,一个规则可以屏蔽某个具体的文件或者某一类或几类文件的提交。可以使用通配符来编写规则,#
作为注释。
# 要忽略提交什么文件
file_name
*.dat
*.py[cod]
db.ini
git add -f file_name.file_type
git check-ignore
来检查屏蔽规则git config --global alias.s_name 'long_command_name'
,比如:git config --global alias.br branch
,就可以使用git br
代替git branch
操作了。例如:
git config --global alias.lg “log --color --graph --pretty=format:‘%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset’ --abbrev-commit”
.git/congif
的[alias]
后,删除别名直接把对应的行删除即可。也可以在用户主目录下的隐藏文件.gitconfig
中也存放了当前用户的Git配置,可以删除文件重新配置命令。总的来说基于Linux系统,在裸Git仓库上配置协议,就能搭建成功。有相关工具来完善和方便管理,Gitosis
管理公钥,使用Gitolite
进行权限管理。
当然还有GitLab
方便搭建私有Git仓库,进行团队管理。