本文是笔者学习廖雪峰的Git教程记录的笔记,算是对其内容的精简,仅供查询和回顾之用。若有疏漏,还请查看其原文。
基本概念
Git进行版本控制,管理的是修改而非文件。分清楚工作区,版本库,暂存区(stage)就能很好地理解其工作原理。
工作区(Working Directory):顾名思义是工作的地方,对文件的创建,修改,添加,删除等都会对其造成影响。比方说我创建的一个项目工程就是一个工作区。
版本库(Repository):工作区中有一个隐藏的目录.git,不算工作区而是Git版本库。
Git版本库最终的就是stage(或者叫index)的暂存区,还有Git默认创建的master分支,以及指向master分支的HEAD指针。
文件的增删变更直接作用在工作区,第一步,变更后add,就添加到了版本库的暂存区。
第二步,git commit提交更改,就是将暂存区的所有内容提交到当前分支。
简单的理解就是,需要提交的文件修改都放在暂存区,然后一次性提交暂存区中的内容到到当前分支。
文件修改和“时光穿梭”(版本回退)
- 场景1:当修改了工作区的文件内容,觉得不合适,想直接丢弃工作区的修改,使用命令:
git checkout -- filenname
- 场景2:当修改了工作区的文件内容,觉得不合适,但是已经通过
git add
添加修改到了暂存区,想直接丢弃工作区的修改,分两步,第一步,使用命令git reset HEAD filename
,就回到了场景1;第二步按照场景1来操作。 - 场景3:已经通过
git commit
提交了不合适的修改到版本库中,想要撤销本次提交,就执行版本退回命令,git reset --hard commid_id
进行时光穿梭。穿梭前可以使用git log
查看历史版本;当还需要重返未来的时候,使用git reflog
查看历史命令。
删除文件
使用rm filename
来在工作区删除文件,现在工作区和版本库就不一致了。
- 场景1:确认删除该文件,使用
git rm filename
命令,然后git commit
- 场景2:属于误删操作,但是还没有提交到版本库,使用命令
git checkout -- filename
,使用版本库中的版本替换到工作区的版本。 - 场景3:已经提交到版本库,发现属于误删操作,执行版本回退来时光穿梭。
分支管理
- 创建和切换分支:
git checkout -b branch_name
.相当于两句指令:git branch branch_name
, 随后git checkout branch_name
ps: 关于Vim重命名文件,在退出之前输入:sav new_file_name
即可,会保存一个相同内容的副本,而不是在当前修改文件中修改,要想这样需要安装特定的插件。
- 查看分支:
git branch
- 创建分支:
git branch <branch_name>
- 切换到分支:
git checkout <branch_name>
- 创建加切换:
git checkout -b <branch_name>
- 合并到当前:
git merge <branch_name>
- 删除分支:
git branch -d <branch_name>
冲突解决
新建分支在上面修改后,add, commit,然后切换到要汇入的分支上,假如此时在当前分支上也做了修改,执行git merge <branch_to_be_merged>
时发现无法合并,使用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@{xxx}>
来恢复,参数是可选的用于多次stash之后选择要恢复的那个。这种方式恢复后stash的内容不删除,需要输入git stash drop
来删除。
另一种方式能够恢复的同时删除stash,即使用git stash pop
。
删除未合并过的分支
场景:导师给了个新需求要做,做完了却悲催地听说不需要了,现在要删除这个分支。git brach -d <feature>
,会提示The branch '<feature>' is note fully merged. If you are sure you want to delete it , run'git branch -D <feature>'
。
所以git branch -D <branch_name>
就是强制删除未曾合并过的分支的命令。
远程分支操作
-
场景1:在本地创建了一个分支,但是远程没有,commit之后希望push到远程比方说Github上,但是不是master分支,而是一个目前还没有创建的分支上。使用
git push -u origin <local_branch_name>
,这样就在远程创建了和local_branch_name
同名分支。 -
场景2:远端已经存在和本地同名或者不同名的分支,希望这时将本地的分支推到远端上,
git push <remote_name> <local_branch_name>:<remote_branch_name>
-
场景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
。
rebase整理push历史
- 场景:本地版本历史过多,有的commit并没有push到远程,所以再查看历史的时候希望只查看push过的提交,使用
git rebase
命令实现。
tag
为commit打上标签
-
场景1:某个工作已经进行了多次的编辑和提交。过了一阵子,导师或者其他人说,请把之前的某次提交打包一下。这时选择查找
commit_id
显得就不是很方便。tag
就相当于是对于commit的起的别名,使用git tag <tag_name>
默认为最近的一次提交打上标签,在产看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
就能查看到相应说明文字。
标签操作
- 场景1,打错了,在本地删除:
git tag -d tag_name
- 场景2,推送某次提交的标签到远程:
git push origin tag_name
- 场景3,推送全部尚未推送到远程的标签:
git push origin --tags
- 场景4,删除远程的标签:先要删除本地的要删除的标签。然后执行,
git push origin :refs/tags/tag_name
,然后去远程查看标签是否被删除。
自定义Git
除了配置user.name
, user.email
之外还可以配置一些东西。
- 场景,命令行工作颜色单调:配置显示ui,
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配置,可以删除文件重新配置命令。
架设Git服务器
参考1
参考2
总的来说基于Linux系统,在裸Git仓库上配置协议,就能搭建成功。有相关工具来完善和方便管理,Gitosis
管理公钥,使用Gitolite
进行权限管理。
当然还有GitLab
方便搭建私有Git仓库,进行团队管理。