git教程 自学笔记

来源:互联网 发布:80端口被system占用 编辑:程序博客网 时间:2024/04/29 06:41

《git教程》学习自http://www.liaoxuefeng.com/wiki/0013739516305929606dd18361248578c67b8067c8c017b000


创建一个版本库

$ cd learngit
$ git init


查看git仓库状态,对比文件,把文件添加到仓库

$ git status
$ git diff readme.txt 
$ git add readme.txt  
$ git commit -m "wrote a readme file"


查看日志

$ git log
$ git log --pretty=oneline


上一个版本就是HEAD^,上上一个版本就是HEAD^^,当然往上100个版本写100个^比较容易数不过来,所以写成HEAD~100。

回退到上一个版本

$ git reset --hard HEAD^


指定回到某个版本

$ git reset --hard 3628164

用来显示你曾经的每一次命令

$ git reflog

工作区(Working Directory):就是你在电脑里能看到的目录

版本库(Repository):工作区有一个隐藏目录“.git”,这个不算工作区,而是Git的版本库。

Git的版本库里存了很多东西,其中最重要的就是称为stage(或者叫index)的暂存区,还有Git为我们自动创建的第一个分支master,以及指向master的一个指针叫HEAD。

第一步是用“git add”把文件添加进去,实际上就是把文件修改添加到暂存区;

第二步是用“git commit”提交更改,实际上就是把暂存区的所有内容提交到当前分支。


Git跟踪并管理的是修改,而非文件。

“git commit”只负责把暂存区的修改提交


丢弃工作区的修改,“--”很重要,没有“--”,就变成了“创建一个新分支”的命令

$ git checkout -- readme.txt

一种是readme.txt自修改后还没有被放到暂存区,现在,撤销修改就回到和版本库一模一样的状态;

一种是readme.txt已经添加到暂存区后,又作了修改,现在,撤销修改就回到添加到暂存区后的状态。

总之,就是让这个文件回到最近一次git commit或git add时的状态。


从版本库中删除该文件

$ git rm test.txt
$ git commit -m "remove test.txt"


把误删的文件恢复到最新版本

$ git checkout -- test.txt


添加远程仓库

$ git remote add origin git@github.com:michaelliao/learngit.git
远程库的名字就是origin,这是Git默认的叫法,也可以改成别的,但是origin这个名字一看就知道是远程库。


把本地库的所有内容推送到远程库上

$ git push -u origin master
我们第一次推送master分支时,加上了-u参数,Git不但会把本地的master分支内容推送的远程新的master分支,还会把本地的master分支和远程的master分支关联起来,在以后的推送或者拉取时就可以简化命令


从现在起,只要本地作了提交,就可以通过命令:

$ git push origin master

假如远程库已经准备好了,下一步是用命令git clone克隆一个本地库:

$ git clone git@github.com:michaelliao/gitskills.git

当我们创建新的分支,例如dev时,Git新建了一个指针叫dev,指向master相同的提交,再把HEAD指向dev,就表示当前分支在dev上,从现在开始,对工作区的修改和提交就是针对dev分支了

假如我们在dev上的工作完成了,就可以把dev合并到master上。Git怎么合并呢?最简单的方法,就是直接把master指向dev的当前提交,就完成了合并

合并完分支后,甚至可以删除dev分支。删除dev分支就是把dev指针给删掉,删掉后,我们就剩下了一条master分支


创建dev分支,然后切换到dev分支

$ git checkout -b dev
git checkout命令加上-b参数表示创建并切换,相当于以下两条命令:

$ git branch dev$ git checkout dev

git branch命令查看当前分支

$ git branch


假如dev分支的工作已经完成,我们就可以切换回master分支

$ git checkout master

把dev分支的工作成果合并到master分支上,git merge命令用于合并指定分支到当前分支:

$ git merge dev

合并完成后,就可以放心地删除dev分支了

$ git branch -d dev

如果merge时发生冲突,必须手动解决冲突后再提交

$ git merge feature1Auto-merging readme.txtCONFLICT (content): Merge conflict in readme.txtAutomatic merge failed; fix conflicts and then commit the result.
$ git status# On branch master# Your branch is ahead of 'origin/master' by 2 commits.## Unmerged paths:#   (use "git add/rm <file>..." as appropriate to mark resolution)##       both modified:      readme.txt#no changes added to commit (use "git add" and/or "git commit -a")
修改readme.txt后保存,再提交


当使用“Fast forward”模式,但这种模式下,删除分支后,会丢掉分支信息。如果想禁用“Fast forward”,则:

准备合并dev分支,请注意--no-ff参数,表示禁用“Fast forward”,因为本次合并要创建一个新的commit,所以加上-m参数,把commit描述写进去。

$ git merge --no-ff -m "merge with no-ff" dev

bug修复(新需求的开发工作只进行到一半,还没法提交,预计完成还需1天时间。但是,必须在两个小时内修复一个线上的bug,怎么办?):

幸好,Git还提供了一个stash功能,可以把当前工作现场“储藏”起来,等以后恢复现场后继续工作:

$ git stash
假定需要在master分支上修复,就从master创建临时分支


修复bug

$ git checkout master
$ git checkout -b issue-101
修改出现bug的readme.txt文件。
$ git add readme.txt
$ git commit -m "fix bug 101"
$ git checkout master
$ git merge --no-ff -m "merged bug fix 101" issue-101
$ git branch -d issue-101
 

回到dev分支干活

$ git checkout dev
git stash list命令看看

$ git stash list

方式有2种:

一是用git stash apply恢复,但是恢复后,stash内容并不删除,你需要用git stash drop来删除;

另一种方式是用git stash pop,恢复的同时把stash内容也删了:

$ git stash pop


当一个分支已经提交,但是还没有合并,此时想删除该分支,例如:

feature-vulcan分支还没有被合并,如果删除,将丢失掉修改,如果要强行删除,需要使用命令git branch -D feature-vulcan

$ git branch -D feature-vulcan


要查看远程库的信息,用git remote:或者,用git remote -v显示更详细的信息:

$ git remote
$ git remote -v

把该分支上的所有本地提交推送到远程库。推送时,要指定本地分支,这样,Git就会把该分支推送到远程库对应的远程分支上:

$ git push origin master
或者其他分支,比如dev

$ git push origin dev

哪些分支需要推送,哪些不需要呢?

  • master分支是主分支,因此要时刻与远程同步;

  • dev分支是开发分支,团队所有成员都需要在上面工作,所以也需要与远程同步;

  • bug分支只用于在本地修复bug,就没必要推到远程了,除非老板要看看你每周到底修复了几个bug;

  • feature分支是否推到远程,取决于你是否和你的小伙伴合作在上面开发。

总之,就是在Git中,分支完全可以在本地自己藏着玩,是否推送,视你的心情而定!


你的小伙伴要在dev分支上开发,就必须创建远程origin的dev分支到本地,于是他用这个命令创建本地dev分支:

$ git checkout -b dev origin/dev
现在,他就可以在dev上继续修改,然后,时不时地把dev分支push到远程:

$ git commit -m "add /usr/bin/env"
$ git push origin dev

你的小伙伴已经向origin/dev分支推送了他的提交,而碰巧你也对同样的文件作了修改,并试图推送:

$ git add hello.py $ git commit -m "add coding: utf-8"[dev bd6ae48] add coding: utf-8 1 file changed, 1 insertion(+)$ git push origin devTo git@github.com:michaelliao/learngit.git ! [rejected]        dev -> dev (non-fast-forward)error: failed to push some refs to 'git@github.com:michaelliao/learngit.git'hint: Updates were rejected because the tip of your current branch is behindhint: its remote counterpart. Merge the remote changes (e.g. 'git pull')hint: before pushing again.hint: See the 'Note about fast-forwards' in 'git push --help' for details.
推送失败,因为你的小伙伴的最新提交和你试图推送的提交有冲突,解决办法也很简单,Git已经提示我们,先用git pull把最新的提交从origin/dev抓下来,然后,在本地合并,解决冲突,再推送:

$ git pullremote: Counting objects: 5, done.remote: Compressing objects: 100% (2/2), done.remote: Total 3 (delta 0), reused 3 (delta 0)Unpacking objects: 100% (3/3), done.From github.com:michaelliao/learngit   fc38031..291bea8  dev        -> origin/devThere is no tracking information for the current branch.Please specify which branch you want to merge with.See git-pull(1) for details    git pull <remote> <branch>If you wish to set tracking information for this branch you can do so with:    git branch --set-upstream dev origin/<branch>
git pull也失败了,原因是没有指定本地dev分支与远程origin/dev分支的链接,根据提示,设置dev和origin/dev的链接:

$ git branch --set-upstream dev origin/devBranch dev set up to track remote branch dev from origin.

再pull:

$ git pullAuto-merging hello.pyCONFLICT (content): Merge conflict in hello.pyAutomatic merge failed; fix conflicts and then commit the result.
这回git pull成功,但是合并有冲突,需要手动解决,解决的方法和分支管理中的解决冲突完全一样。解决后,提交,再push:

$ git commit -m "merge & fix hello.py"[dev adca45d] merge & fix hello.py$ git push origin devCounting objects: 10, done.Delta compression using up to 4 threads.Compressing objects: 100% (5/5), done.Writing objects: 100% (6/6), 747 bytes, done.Total 6 (delta 0), reused 0 (delta 0)To git@github.com:michaelliao/learngit.git   291bea8..adca45d  dev -> dev

因此,多人协作的工作模式通常是这样:

  1. 首先,可以试图用git push origin branch-name推送自己的修改;

  2. 如果推送失败,则因为远程分支比你的本地更新,需要先用git pull试图合并;

  3. 如果合并有冲突,则解决冲突,并在本地提交;

  4. 没有冲突或者解决掉冲突后,再用git push origin branch-name推送就能成功!

如果git pull提示“no tracking information”,则说明本地分支和远程分支的链接关系没有创建,用命令git branch --set-upstream branch-name origin/branch-name

这就是多人协作的工作模式,一旦熟悉了,就非常简单。



发布一个版本时,我们通常先在版本库中打一个标签,这样,就唯一确定了打标签时刻的版本。将来无论什么时候,取某个标签的版本,就是把那个打标签的时刻的历史版本取出来。所以,标签也是版本库的一个快照。

切换到需要打标签的分支上,然后:

$ git tag v1.0
查看历史提交的commit id:

$ git log --pretty=oneline --abbrev-commit6a5819e merged bug fix 101cc17032 fix bug 1017825a50 merge with no-ff6224937 add merge59bc1cb conflict fixed400b400 & simple75a857c AND simplefec145a branch testd17efd8 remove test.txt...
比方说要对“add merge”这次提交打标签,它对应的commit id是“6224937”,敲入命令:

$ git tag v0.9 6224937
再用命令git tag查看标签:

$ git tag

注意,标签不是按时间顺序列出,而是按字母排序的。

可以用git show tagname查看标签信息:

$ git show v0.9commit 622493706ab447b6bb37e4e2a2f276a20fed2ab4Author: Michael Liao <askxuefeng@gmail.com>Date:   Thu Aug 22 11:22:08 2013 +0800    add merge...

还可以创建带有说明的标签,用-a指定标签名,-m指定说明文字:

$ git tag -a v0.1 -m "version 0.1 released" 3628164

如果标签打错了,也可以删除:

$ git tag -d v0.1

如果要推送某个标签到远程,使用命令git push origin tagname:

$ git push origin v1.0
或者,一次性推送全部尚未推送到远程的本地标签:

$ git push origin --tags
如果标签已经推送到远程,要删除远程标签就麻烦一点,先从本地删除:

$ git tag -d v0.9

然后,从远程删除。删除命令也是push,但是格式如下:

$ git push origin :refs/tags/v0.9To git@github.com:michaelliao/learngit.git - [deleted]         v0.9



在Git工作区的根目录下创建一个特殊的.gitignore文件,然后把要忽略的文件名填进去,Git就会自动忽略这些文件。

忽略文件的原则是:

  1. 忽略操作系统自动生成的文件,比如缩略图等;
  2. 忽略编译生成的中间文件、可执行文件等,也就是如果一个文件是通过另一个文件自动生成的,那自动生成的文件就没必要放进版本库,比如Java编译产生的.class文件;
  3. 忽略你自己的带有敏感信息的配置文件,比如存放口令的配置文件。


配置别名:

我们只需要敲一行命令,告诉Git,以后st就表示status

$ git config --global alias.st status






原创粉丝点击