Github初始化、提交、分支等的概念和实例

首先你最好把自己介绍给git系统

git config global user.name Your Name

git config global user.email [email protected]

现在我手头已经有了一个项目(假设只有main.c一个文件),而且这个项目的全部代码和资源都放在rocrocket目录下,我将用下面的步骤来导入这个项目:

cd rocrocket/

git init

ls -a

git add .

git commit

git init命令用于初始化当前所在目录的这个项目,shell返回的提示表明已经建立了一个.git隐藏目录来保存这个项目目

前的进展信息。我们可以用ls -a 看到它。

git add .这个命令要求git给我目前的这个项目制作一个快照snapshot(快照只是登记留名,快照不等于记录在案,git管快照叫做索引index)。快照一般会暂时存储在一个临时存储区域中。

git commit用于将快照里登记的内容永久写入git仓库中,也就是开发者已经想好了要提交自己的开发成果了。

在输入git commit并按回车时会转到一个vi窗口,要求开发者输入这次提交的版本和开发信息。意思就是说这个项目目前的版本是多少,已经完成了哪些功能,还有哪些功能是需要以后完成的等等信息.

这次我们来研究“改进代码之后怎么提交给git”。

cat -n main.c

进入编辑(vi)模式对内容修改后

接下来的两道工序主要是由开发者最后确认一下“自己的修改”:

git diff cached

这个git diff cached是用来查看index file 和仓库之间代码的区别的。由于我们目前只是在working tree里做了修改,

还没有报告给index file,所以使用此命令显然会输出空信息。而如果省略–cached选项的话,就是比较working treeindex file 的区别,由于我们的确在working tree里做了修改,所以使用git diff后会输出修改信息。

使用git diff了解了不同之后,还可以使用git status命令来获取整体改动的信息:

git status

可以看到提示信息“changed but not updated”,就是说git发现你有已经修改了但还未git add的内容。

如果git提示说“Changes to be committed”,那就是表明git发现了你已经git add但还未git commit的内容。

如果git提示说“Untracked files”,那么就是你增加了新文件或者在某个子目录下增加了新文件。

下面该进入提交阶段了。首先运行

git add main.c

这句是要告诉git,我已经修改了main.c文件,你(指git)去检查一下。当然,如果你新增加了一个文件,比如

new.c,也需要在这里先执行git add new.c告诉git

提交我的工作:

git commit

至此,我的修改工作完成了,而且也顺利地提交给了git。还是不放心?来查查:

git log

总结一下

如果修改了项目代码,先git add你修改过的文件,再git diffgit status查看确认,然后git commit提交,然后输入

你的开发日志,最后git log再次确认。

现在教给你一个偷懒方法,那就是git commit -a,这个命令可以直接提交所有修改,省去了你git addgit diffgit commit的工序,可谓一条龙服务。

但是,此处有一点应该注意,那就是git commit -a无法把新增文件或文件夹加入进来,所以,如果你新增了文件或文件夹,那么就要老老实实的先git add .,再git commit但如果你觉得git log给出的信息太单薄了,可以使用git log -p,这样git不但会给出开发日志,而且会显示每个开发版本的代码区别所在。

如何管理分支:

还是接着我们之前的main.c的项目走。我想试着开发一个报时功能加入到main.c中,但我不保证这个功能一定能够实现。这个时候可以运行git branch命令来开启一个实验分支:

git branch experimental

查看分支:

Git branch

我要进行报时功能的开发,当然我就要切换到experimental分支:

git checkout experimental

修改后如下:

     cat -n main.c

1    #include<stdio.h>

2    #include<time.h>

3    int main()

4    {

5    time_t mytime;

6    struct tm *mylocaltime;

7    mytime=time(NULL);

8    mylocaltime=localtime(&mytime);

9    printf(Year:%d\n,mylocaltime->tm_year+1900);

10    printf(Month:%d\n,mylocaltime->tm_mon+1);

11    printf(Day:%d\n,mylocaltime->tm_mday);

12    printf(Hour:%d\n,mylocaltime->tm_hour);

13    printf(Min:%d\n,mylocaltime->tm_min);

14    printf(Second:%d\n,mylocaltime->tm_sec);

15    printf(Version: 0.02\n);

16    printf(Hello world!\n);

17    return 0;

假设运行正常

下面的任务就是提交程序到分支项目:(注意虽然已经确认了分支的正确性,但还是不能着急报告给“主干道”,而还要先在分支上提交工作)

 

git commit -a

然后就可以切换到“主干道”了:

git checkout master

此时,无论使用log 或是status命令都无法看到刚才在experimental分支所进行的工作。

下面,我们就来合并“分支”和“主干道”:

git merge experimental

没有错误的话  gitk  会出来什么?

删除分支: git branch -d experimental

在这里使用的是小写的-d,表示“在分支已经合并到主干后删除分支”。

如果使用大写的-D的话,则表示“不论如何都删除分支”,-D当然使用在“分支被证明失败”的情况下喽。

 

合作开发:

目前我已经拥有的项目放在/home/rocrocket/git-study/rocrocket里面,其他人可以通过如下方式获得代码:

git clone /home/rocrocket/git-study/rocrocket  myrepo

这样小强就克隆了我的工作成果到了他的家目录中的myrepo中。OK,小强可以对myrepo里的程序进行改进了。在修改完毕之后,小强使用git commit -a来提交他的改进成果。此后,小强告诉我他已经完成了改进工作,让我去查看一下。

我为了肯定小强的劳动成果(也就是将他的改进合并到项目中来),我是这么干的:

cd /home/rocrocket/git-study/rocrocket

git pull /home/xiaoqiang/myrepo master

这句话的意思是:将小强的工作的master合并到我的当前的分支上(通常是主干道)。当然,如果这期间,我也修改了项目,那么git pull的时候如果报告冲突,我也是需要自己来搞定的。其实pull命令完成了两个动作,首先从远端分支获取diff信息,第二个动作就是将改变合并到本地分支中。读者要记住一个小技巧,那就是“git pull .”命令,它和git merge的功能是一样的,以后完全可以用git pull .来代替git merge

 

git fetch /home/bob/myrepo master:bobworks //此命令意思是提取出bob修改的代码内容,然后放到我(rocrocket)工作目录下的bobworks分支中。之所以要放到分支中,而不是master中,就是要我先仔仔细细看看bob的开发成果,如果我觉得满意,我再mergemaster中,如果不满意,我完全可以直接git branch -D掉。

$git whatchanged -p master..bobworks //用来查看bob都做了什么

$git checkout master //切换到master分区

$git pull . bobworks //如果我检查了bob的工作后很满意,就可以用pull来将bobworks分支合并到我的项目中了

$git branch -D bobworks //如果我检查了bob的工作后很不满意,就可以用-D来放弃这个分支就可以了

过了几天,bob如果想继续帮助我开发,他需要先同步一下我这几天的工作成果,只要在其当初clonemyrepo目录下执行git pull即可:

#git pull //不用加任何参数,因为当初clone的时候,git已经记住了我(rocrocket)的工作目录,它会直接找到我的目录来取。

 

对文档层次的概括:(很精彩,很简洁)

将 Current working directory 记为 (1)

将 Index file 记为 (2)

将 Git repository 记为 (3)

他们之间的提交层次关系是 (1) -> (2) -> (3)

git add完成的是(1) -> (2)

git commit完成的是(2) -> (3)

git commit -a两者的直接结合

从时间上看,可以认为(1)是最新的代码,(2)比较旧,(3)更旧

按时间排序就是 (1) <- (2) <- (3)

git diff得到的是从(2)(1)的变化

git diff cached得到的是从(3)(2)的变化

git diff HEAD得到的是从(3)(1)的变化

 

从独立开发者的角度进行的一次操作:

$ git-init

$ git add .

$ git commit -m important of mypro source tree.

$ git tag v2.43 //给这个commit起了一个简单的名字v2.43

下面我们建立分支并继续开发:

$ git checkout -b alsa-audio //-b用于建立一个新的分支,分支名称为alsa-audio,并且转移到此分支

(开发/编译/测试)

$ git checkout — curses/ux_audio_oss.c //用于取消对curses/ux_audio_oss.c文件的修改

$ git add curses/ux_audio_alsa.c //如果你在这一阶段的开发过程中增加了新文件,那么你应该用git-add告知git仓库,当然,

如果你只是修改或删除,那么使用git-commit -a就可以让git查觉到了。

(开发/编译/测试)

$ git diff HEAD //查看一下我们即将commit的内容

$ git commit -a -s //提交

(开发/编译/测试)

$ git reset soft HEAD^ //回复到上一次commit的代码。–soft选项表示不改动index fileworking tree中的内容

(开发/编译/测试)

$ git diff ORIG_HEAD //look at the changes since the premature commit we took back

$ git commit -a -c ORIG_HEAD //重新提交,-c ORIG_HEAD表示使用原有的提交信息

$ git checkout master

$ git merge alsa-audio

$ git log since=3 days ago

$ git log v2.43.. curses/    //查看自从v2.43以来的curses目录下的代码变化信息

 

 

合作开发者的角度:

$git clone git://git.kernel.org/pub/scm//torvalds/linux-2.6 my2.6

$cd my2.6

(开发…编译…测试…)

$git commit -a -s //-s选项用于在commit信息后加上结束标志

$git format-patch origin //从本地分支生成patch,用于email提交

$git pull //origin取出更新并合并到当前分支

$git log -p ORIG_HEAD.. arch/i386 include/asm-i386

$git pull git://git.kernel.org/pub//jgarzik/libata-dev.git ALL //从特定git仓库取出变更并合并。

$git reset hard ORIG_HEAD //恢复到上一次的内容

$git gc //用垃圾回收机制清除由于reset而造成的垃圾代码

$git fetch tags //origin取出tags并存储到.git/refs/tags

 

两点提交状态时的说明:

很明显可以知道:

Changes to be committed表示已经存在于index file 里,但尚未提交。

Changed but not updated表示在working tree已经做修改,但还没有使用git add登记到index file 里。

 

git branch branchname 就是根据commit来建立的新分支。

ps:如果你学有余力,我再告诉你一个信息。在你git branch一个新分支后,在目录.git/refs/heads目录下会多出一个新的文件,对应于新分支的名称,用来记录新分支下对应的“最后一次commit的信息”。

ps:如果你学有余力,我还要告诉你一个信息。当你git branch一个新分支并checkout转移到这个新分支后,.git目录下的HEAD文件会相应的改变,它的内容将对应着新分支下“最后一次commit的信息”。

你可能感兴趣的:(github)