学习笔记来源于
http://www.liaoxuefeng.com/wiki/0013739516305929606dd18361248578c67b8067c8c017b000感谢原作者的教程
Git Learning 1
创建版本库
版本库又名仓库,英文名repository,你可以简单理解成一个目录,这个目录里面的所有文件都可以被Git管理起来,每个文件的修改、删除,Git都能跟踪,以便任何时刻都可以追踪历史,或者在将来某个时刻可以“还原”。
git init : to set the current dirctory as one that can be managed by Git
git add [filename] : to add files to the repository
git commit -m “DESCRIPTION” : to commit the change that you made and your “DESCRIPTION”
时光穿梭机
git status : to know the current status of the respository
git diff : to konw the specific difference
要随时掌握工作区的状态,使用git status命令。如果git status告诉你有文件被修改过,用git diff可以查看修改内容。
git log : to know the current log of the repository
to see the log more clearly by adding [--pretty=oneline]
git log 命令显示的前缀字符串为[commit id],是一个SHA1计算出来的一个非常大的数字,用十六进制表示.
为什么commit id需要用这么一大串数字表示呢?
因为Git是分布式的版本控制系统,后面我们还要研究多人在同一个版本库里工作,
如果大家都用1,2,3……作为版本号,那肯定就冲突了。
每提交一个新版本,实际上Git就会把它们自动串成一条时间线。如果使用可视化工具查看Git历史,就可以更清楚地看到提交历史的时间线.
git reset –hard [version] : to reset the git back to the [version]
[vesrsion]:HEAD represent the current version
HEAD^ represent the previous one version
HEAD~num represent the previous number version
if you want to reset the git to the later version,
you need to remembr some txt of the [coommit id]
then use it as the [version] option
Git的版本回退速度非常快,因为Git在内部有个指向当前版本的HEAD指针,当你回退版本的时候,Git仅仅是把HEAD改为指向后来版本。
git reflog : to see every command and its [commit id]
so that you can know the [commit id] by this command :)
在Git中,总是有后悔药可以吃的。当你用$ git reset –hard HEAD^回退到add distributed版本时,再想恢复到append GPL,就必须找到append GPL的commit id。Git提供了一个命令git reflog用来记录你的每一次命令。
工作区&暂存区
工作区有一个隐藏目录.git,这个不算工作区,而是Git的版本库。
Git的版本库里存了很多东西,其中最重要的就是称为stage(或者叫index)的暂存区,还有Git为我们自动创建的第一个分支master,以及指向master的一个指针叫HEAD。
用git add把文件添加进去,实际上就是把文件修改添加到暂存区;
用git commit提交更改,实际上就是把暂存区的所有内容提交到当前分支。
撤销修改
之所以说Git比其他版本控制系统设计得优秀,是因为Git跟踪并管理的是修改,而非文件。
git checkout –[filename] : to discard changes of the file
it works before your "git add [filename]"
git reset HEAD [filename] : to unstage
it works after your "git add [filename]" before your "git commit"
用git reset HEAD [filename]丢弃暂存区的修改;
用git checkout – [filename]丢弃工作区的修改。
删除文件
git rm [filename] : to remove the file
git checkout – [filename] : to cancel your wrong deleting
在git rm [filename]后,用git commit -m “remove the xxx file”提交删除操作
添加远程仓库
本地Git仓库和GitHub仓库之间的传输是通过SSH加密的.
GitHub允许你添加多个Key。假定你有若干电脑,你一会儿在公司提交,一会儿在家里提交,只要把每台电脑的Key都添加到GitHub,就可以在每台电脑上往GitHub推送了。
在本地的仓库下运行如下命令:
git remote add [origin] git@github.com:[username]/[repository_name]
[origin] is the default name of the remote repository
git push -u [origin] master
push everthing of the local repository to the remote repository
由于远程库是空的,我们第一次推送master分支时,加上了-u参数,Git不但会把本地的master分支内容推送的远程新的master分支,还会把本地的master分支和远程的master分支关联起来,在以后的推送或者拉取时就可以简化命令.
从现在起,只要本地作了提交,就可以通过命令:
git push [origin] master
把本地master分支的最新修改推送至GitHub.
克隆远程库:
git clone git@github.com:[username]/[repository_name]
to clone the remote repository to the local
Git Learning 2
分支的创建于合并
每次提交,Git都把它们串成一条时间线,这条时间线就是一个分支。截止到目前,只有一条时间线,在Git里,这个分支叫主分支,即master分支。HEAD严格来说不是指向提交,而是指向master,master才是指向提交的,所以,HEAD指向的就是当前分支。
一开始的时候,master分支是一条线,Git用master指向最新的提交,再用HEAD指向master,就能确定当前分支,以及当前分支的提交点。
每次提交,master分支都会向前移动一步,这样,随着你不断提交,master分支的线也越来越长。
当我们创建新的分支,例如dev时,Git新建了一个指针叫dev,指向master相同的提交,再把HEAD指向dev,就表示当前分支在dev上。
不过,从现在开始,对工作区的修改和提交就是针对dev分支了,比如新提交一次后,dev指针往前移动一步,而master指针不变。
假如我们在dev上的工作完成了,就可以把dev合并到master上。Git怎么合并呢?最简单的方法,就是直接把master指向dev的当前提交,就完成了合并。
合并完分支后,甚至可以删除dev分支。删除dev分支就是把dev指针给删掉,删掉后,我们就剩下了一条master分支。
git checkout -b [branch_name] : switch to a new branch [branch_name]
This command equals to "git branch [b_name]" + "git checkout [b_name]"
git branch : to see your branch
git branch [b_name] : to create a new branch
git merge [branch_name] : to merge [b_name] to current branch
git branch -d [branch_name] : to delete one branch
解决分支冲突
Git用<<<<<<<,=======,>>>>>>>标记出不同分支的内容。
当Git无法自动合并分支时,就必须首先解决冲突。解决冲突后,再提交,合并完成。
用git log –graph命令可以看到分支合并图。
using --pretty=onelien to see it more clearly
分支策略
在实际开发中,我们应该按照几个基本原则进行分支管理:
首先,master分支应该是非常稳定的,也就是仅用来发布新版本,平时不能在上面干活;
那在哪干活呢?干活都在dev分支上,也就是说,dev分支是不稳定的,到某个时候,比如1.0版本发布时,再把dev分支合并到master上,在master分支发布1.0版本;
你和你的小伙伴们每个人都在dev分支上干活,每个人都有自己的分支,时不时地往dev分支上合并就可以了。
合并分支时,加上 –no-ff 参数就可以用普通模式合并,合并后的历史有分支,能看出来曾经做过合并,而fast forward合并就看不出来曾经做过合并。
Bug分支
在Git中,由于分支是如此的强大,所以,每个bug都可以通过一个新的临时分支来修复,修复后,合并分支,然后将临时分支删除。
git stash : to save working directory
首先确定要在哪个分支上修复bug,假定需要在master分支上修复,就从master创建临时分支.
git stash list : to see the saved working directory
git stash pop : to return to the working directory and remove the stash
git branch -D [branch_name] : to delete the branch which has not been mergerd
多人协作
git remote : to see the information of the remote repository
adding -v to konw more
git checkout -b [local_branch] [remote_branch] : to clone the remote branch to the local branch
If we want to push something to the remote repository while others have changed the same file:
using git pull to pull the commit and then merge it locally to fix the conflict. So that we can push things successfully.
p.s: using "git branch --set-upstream [local_branch] [remote_branch]"
to set the connection between local branch and remote branch
Then we can pull it successfully.
Git Learning 3
标签管理
发布一个版本时,我们通常先在版本库中打一个标签(tag),这样,就唯一确定了打标签时刻的版本。将来无论什么时候,取某个标签的版本,就是把那个打标签的时刻的历史版本取出来。所以,标签也是版本库的一个快照。
Git的标签虽然是版本库的快照,但其实它就是指向某个commit的指针(跟分支很像对不对?但是分支可以移动,标签不能移动),所以,创建和删除标签都是瞬间完成的。
git tag [tag-name] : to add one tag to the current commit
git tag [tag-name] [commit-id] : to add one tag to the [c-id] commit
git show [tag-name] : to see the information of one tag
git tag -a [tag-name] -m “description” : to add tag’s information
git tag -d [tag-name] : to delete one tag
git push [remote-branch] [tag-name] : to push one tag to the remote commit
git push [remote-branch] –tags : to push all local tags to the remote commit
git push [remote-branch] :refs/tags/[tag-name] : to delete one remote tag
花了两天时间学习了git以及github.com的使用,感觉很有收获。
这样的版本控制对以后的学习、研究、开发都会很有帮助。