本文是笔者学习廖雪峰的Git教程记录的笔记,算是对其内容的精简,仅供查询和回顾之用。若有疏漏,还请查看其原文。
Git进行版本控制,管理的是修改而非文件。分清楚工作区,版本库,暂存区(stage)就能很好地理解其工作原理。
工作区(Working Directory):顾名思义是工作的地方,对文件的创建,修改,添加,删除等都会对其造成影响。比方说我创建的一个项目工程就是一个工作区。
版本库(Repository):工作区中有一个隐藏的目录.git,不算工作区而是Git版本库。
Git版本库最终的就是stage(或者叫index)的暂存区,还有Git默认创建的master分支,以及指向master分支的HEAD指针。
文件的增删变更直接作用在工作区,第一步,变更后add,就添加到了版本库的暂存区。
第二步,git commit提交更改,就是将暂存区的所有内容提交到当前分支。
简单的理解就是,需要提交的文件修改都放在暂存区,然后一次性提交暂存区中的内容到到当前分支。
git checkout -- filennamegit add添加修改到了暂存区,想直接丢弃工作区的修改,分两步,第一步,使用命令git reset HEAD filename,就回到了场景1;第二步按照场景1来操作。git commit提交了不合适的修改到版本库中,想要撤销本次提交,就执行版本退回命令,git reset --hard commid_id进行时光穿梭。穿梭前可以使用git log查看历史版本;当还需要重返未来的时候,使用git reflog查看历史命令。使用rm filename来在工作区删除文件,现在工作区和版本库就不一致了。
git rm filename命令,然后git commitgit checkout -- filename,使用版本库中的版本替换到工作区的版本。git checkout -b branch_name.相当于两句指令:git branch branch_name, 随后git checkout branch_nameps: 关于Vim重命名文件,在退出之前输入:sav new_file_name即可,会保存一个相同内容的副本,而不是在当前修改文件中修改,要想这样需要安装特定的插件。
git branchgit 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_namegit push origin tag_namegit push origin --tagsgit 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_typegit 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仓库,进行团队管理。