(1) git/github原理与基本操作ABC中的ABC

来源:互联网 发布:淘宝女装模特拍摄教程 编辑:程序博客网 时间:2024/05/18 00:23

stack overflow和Github

Stack Overflow 一个简单易用的社交问答网站,使用起来很方便。

Github 相对复杂一点,但功能也更强大一些,甚至连google都在使用它来管理开源项目的不同版本。

 
以下将对如何配置Github,如何上传和管理自己的项目进行简单的说明。

 

1. Git的工作原理

 GitHub的核心是一个开源版本控制系统VCS(version control system),称作Git。Git是由设计Linux系统的同一帮人搞出来的。

 如果想了解更多有关Git的东西,不妨看看这里:http://progit.org/book/ch1-3.html

 

这里简单说明一下:

首先是一般的版本控制系统的工作方式:


然后是Git的工作方式:

 

也就是说,每次提交版本变动的时候,git会保存一个快照(snapshot)。如果文件没有被更改,git也不会再次保存,而是提供一个到原来文件的链接。这样一来,git更像是一个小型的文件系统。

此外,git的所有操作都可以是本地的,仅仅在将新版本的内容上传到服务器上时才需要连接网络。

git里面使用了SHA-1检验,因此,你几乎不可能瞒过git而对项目代码进行任何修改。

git只会添加数据,而不会删除数据。因此不要担心我们做一些测试时会破坏原有的数据。


git的三种状态:已提交committed,已更改modified,和已标记staged

已提交表示数据已经安全存储在本地数据库,

已修改表示已经修改了文件,但还没有提交到数据库,

已标记表示已经在当前版本标记了一个更改的文件,以便进入下一次提交的快照。

参看下图:

 

Git目录是Git保存元数据对象数据库的地方。这也是Git最重要的部分。每次克隆镜像仓库的时候,实际拷贝的就是这个目录里面的数据。

working directory是项目某个版本的内容。从项目中取出某个版本的所有文件和目录,用以开始后续工作的叫做工作目录。这些文件实际上都是从 git 目录中的压缩对象数据库中提取出来的,接下来就可以在工作目录中对这些文件进行编辑。

staging area是一个简单的文件,通常包含在Git目录中。其中存储了将要进入下一次提交的信息。有时候人们会把这个文件叫做索引文件,不过标准说法还是叫暂存区域。

说明:

git是一个分布式的版本控制系统,也就是在你的本地有完整的一个仓库的备份,所以你几乎所有的操作都可以在本地完成,处理速度非常快,因为本地有完的服务器数据镜像。

暂存区指的是文件已经修改,并且添加的版本控制追踪中,在下一次提交的时候即可提交到代码仓库中。 之所以有暂存区,是因为git的所有存入仓库的操作都是针对暂存区的文件进行的。

很多刚刚接触git的会被git的本地数据库(git directory)弄晕,因为git本地保存了一个仓库镜像,所以你的所有操作都是对本地这个仓库进行操作的。这么理解就非常方便了。

git directory 经常被称为HEAD,就是当前的工作的分支,以后会经常遇到HEAD这个词。这里也可以这么理解,


就是git的本地仓库分为三棵“树”,

一个是工作目录,

一个是暂存区,成为索引区,记录下一次提交到仓库的文件,

还有就是HEAD了,相当与仓库的本地备份。


Git的基本工作流程如下:

1.在working directory中修改文件。

2.标识(stage)文件,并将文件快照添加到staging area。

3.执行commit,将获取staging area中的文件,并将快照永久保存到Git目录中。


2. git安装

http://www.woiweb.net/github-gitshell-tutorial.html

https://help.github.com/articles/set-up-git/#platform-windows (各个操作系统的配置可查)

3. git基本配置

以win7为例,下载客户端:http://github-windows.s3.amazonaws.com/GitHubSetup.exe,安装完成后,会在桌面上出现两个图标,Git Shell和GitHub。两个图标分别是命令行工具和图形界面,我们先来学习使用shell。

1、双击打开Git Shell,【win7用户使用管理员权限打开】

2、输入git config --global user.name "pjm", 注册的用户名

3、输入git config --global user.email "userregister@xx.cn", 注册邮箱

      上面两步在客户端配置你的git帐户 ,  git config --list命令查看git 配置项列表

-------------------------------------------------------------------------------------------------------

1★★★★★★★

假设我们的虚拟项目是某财务系统,计算某个公司的纳税额等信息。先在github中创建一个这个项目的repo, 命名为finance.

创建好这个repo以后,github给出了一些基本的命令如下:

[html] view plaincopy
  1. Create a new repository on the command line  
  2.   
  3. touch README.md  
  4. git init  
  5. git add README.md  
  6. git commit -m "first commit"  
  7. git remote add origin https://github.com/weixingstudio/finance.git  
  8. git push -u origin master  

  1. Push an existing repository from the command line  
  2.   
  3. git remote add origin https://github.com/xxxxxname/finance.git  
  4. git push -u origin master  

首先我们在我们的本地目录中创建这个项目,最初的项目之包含一个README文件。

在README中添加一些基本的说明。(我的操作路径Win7 、Git Shell、 D:\githubSpace\FinanceProject\finance)

[html] view plaincopy
  1.  mkdir finance  
  2.  cd finance/  
  3.  ls  
  4.  touch README  
  5.  vi README   
然后在这个目录中初始化我们的git仓库。使用下面的git init命令。初始化命令一般在项目的生命周期中只会使用一次。

[html] view plaincopy
  1. git init  

得到这样的结果:

D:\githubSpace\FinanceProject\finance> git init

Initialized empty Git repository in D:/githubSpace/FinanceProject/finance/.git/


然后可以查看我们当前的项目的状态,使用git status 

  1. git status   
  2. # On branch master  //在分支的主人
  3. #  
  4. # Initial commit    //最初的
  5. #  
  6. # Untracked files:  //无足迹的;无路径的;
  7. #   (use "git add <file>..." to include in what will be committed)  
  8. #  
  9. #   README  
  10. nothing added to commit but untracked files present (use "git add" to track)  
  11. //git自动识别出了我们当前的分支是master,然后出现了一个没有跟踪的文件README,需要将这个文件放入到跟踪列表中。
使用(use "git add" to track)

[html] view plaincopy
  1. git add README  
然后再次查看当前的项目状态:

[html] view plaincopy
  1. git status   
  2. # On branch master  
  3. #  
  4. # Initial commit  
  5. #  
  6. Changes to be committed:  
  7. #   (use "git rm --cached <file>..." to unstage)  
  8. #  
  9. #   new file:   README  
  10. #  
  11. git提示有个新的文件在暂存区中,等待提交,第一部分中提到了,只有在暂存区的文件才能提交到git仓库中。   

然后提交整个项目:

[html] view plaincopy
  1. git commit -m 'my first commit'  
这里的-m是对本次提交进行注释说明,-m和后面的说明可以省略,省略后会自动弹出vim编辑器提示你输入提交说明。

D:\githubSpace\FinanceProject\finance [master +1 ~0 -0]> git commit -m "my first commit From panjm"[master (root-commit) 3c2257f] my first commit From panjm 1 file changed, 2 insertions(+) create mode 100644 README.md
交完成后,我们新建的文件就已经提交到了本地的git仓库中但是,目前我们只是把README这个文件提交到了本地的git仓库中,还没有提交到github的远程仓库中,所以如果你们是几个人协同开发软件的话,你仅仅把代码提交到本地的git仓库中以后,别人还是没有办法在服务器端的代码中看到你提交的代码,所以如果想要将本地的代码提交到服务器中,还需要使用git push将本地的git仓库中的代码(也就是HEAD的代码)推送到github服务器中。

推送代码到github服务器,首先我们需要给本地的项目仓库指定一个对应的远端仓库,使用如下的命令:

[html] view plaincopy
  1. git remote add origin https://github.com/xxxxxname/finance.git  
上面的命令中,git remote add 指的是指定当前项目对应的远端仓库,origin是远端仓库的别名,用来方便今后的提交操作,不用每次都写那么长的一个远程仓库的地址。 https://github.com/xxxxxname/finance.git 是真实的远程仓库的地址。指定了远程仓库后,就可以提交了。

默认情况下,本地新建的项目的分支为master,会自动的对应远程仓库的master分支。

提交代码到github: git push origin master    推送本地代码到origin,推送的分支为master  

D:\githubSpace\FinanceProject\finance [master]> git push -u origin masterCounting objects: 3, done.Delta compression using up to 4 threads.Compressing objects: 100% (2/2), done.Writing objects: 100% (3/3), 328 bytes | 0 bytes/s, done.Total 3 (delta 0), reused 0 (delta 0)To https://github.com/xxxxxname/finance.git * [new branch]      master -> masterBranch master set up to track remote branch master from origin.
推送过程中会提示输入用户名和密码。( win7 git shell 没有提示输入  可能之前输入的记住了)

然后在github中就可以看到我们新添加的README文件了。

-------------------------------------------------------------------------------------------------------

2★★★★★★★

获得远端仓仓库的代码,使用git clone 

$ git clone git://github.com/xxxx/xxxxx.git

你可能已经注意到这里使用的是 clone 而不是 checkout。这是个非常重要的差别Git 收取的是项目历史的所有数据(每一个文件的每一个版本),服务器上有的数据克隆之后本地也都有了。实际上,即便服务器的磁盘发生故障,用任何一个克隆出来的客户端都可以重建服务器上的仓库,回到当初克隆时的状态

如果你想项目克隆下来以后命名为别的名字,可以使用下面的命令:

$ git clone git://github.com/xxxx/xxxx.git alias   (对应目录生成alias的文件夹 ,代码在这里面)
   git clone xxx.git "指定目录" 

-------------------------------------------------------------------------------------------------------

3★★★★★★★

新建一个新的文件,作为项目的第一个正式文件,因为之前我们的项目中已经包含一个README文件,并做过一次项目的提交,所以我们现在项目的一个版本记录了当前版本的所有文件的镜像,我们称为C1。

查看当前项目状态会给出当前项目中的文件的状态,是未跟踪,还是已经修改没暂存,或者已经暂存,或者已经提交等状态。

[html] view plaincopy
  1. git status   
  2. # On branch master  
  3. nothing to commit (working directory clean)  
  4.   
目前我们的项目是一个都已经提交了的项目。然后我们建立一个配置文件,配置项目的应用地点。location, timezone等信息。

[html] view plaincopy
  1. finance$ mkdir config  
  2. finance$ cd config/  
  3. finance/config$ touch configuration
  4. finance/config$ vim configuration   
然后查看当前的项目状态:

[html] view plaincopy
  1. finance$ git status  
  2. # On branch master  
  3. # Untracked files:  
  4. #   (use "git add <file>..." to include in what will be committed)  
  5. #  
  6. #   config/  
  7. nothing added to commit but untracked files present (use "git add" to track)   
出现了未跟踪的文件,文件的状态分为未跟踪,已修改(这个时候已经跟踪),已暂存(放入暂存区),已提交。

使用git add 可以跟踪新的文件

[html] view plaincopy
  1. finance$ git add config/  
  2. finance$ git status   
  3. # On branch master  
  4. # Changes to be committed:  
  5. #   (use "git reset HEAD <file>..." to unstage)  
  6. #  
  7. #   new file:   config/configuration  
  8. #  

这个时候我们的新建的config/configuration文件已经被跟踪,并且被保存到了暂存区,在下一次提交的时候就可以被提交到代码仓库(还是在本地 这要理解)。使用git add添加追踪文件的时候,会自动的将新添加的文件添加到暂存区。


同时,git的提示中也给出了将文件从暂存区移除的方法:git reset HEAD <file>


然后这个时候我们提交所有的暂存区的内容,保存一个软件的版本。因为新添加了一个文件,所以现在保存软件的版本为当前所有文件的快照,我们这里称为C2, C1是C2的父节点。

[html] view plaincopy
  1. finance$ git commit -m 'add configuration file'  
  2. [master 8c4472f] add configuration file  
  3.  1 file changed, 2 insertions(+)  
  4.  create mode 100644 config/configuration  
然后将本地的仓库推送到远端github中进行保存。

[html] view plaincopy
  1. finance$ git push origin master    
  2. To https://github.com/xxxxx/finance.git  
  3.    79ec82e..8c4472f  master -> master 

然后,我们开始给项目增加一些具体的功能性的代码。新建一个function1的文件,假设这个文件包含一些有用的功能代码。

[html] view plaincopy
  1. finance$ touch funciton1  
  2. finance$ vim funciton1   

[html] view plaincopy
  1. finance$ git status   
  2. # On branch master  
  3. # Untracked files:  
  4. #   (use "git add <file>..." to include in what will be committed)  
  5. #  
  6. #   funciton1  
  7. nothing added to commit but untracked files present (use "git add" to track)  
又出现了未追踪的文件。追踪文件git add

[html] view plaincopy
  1. finance$ git add funciton1  
  2. watkins@watkins:~/watkins/finance$ git status   
  3. # On branch master  
  4. # Changes to be committed:  
  5. #   (use "git reset HEAD <file>..." to unstage)  
  6. #  
  7. #   new file:   funciton1  
  8. #    
然后我们可以看到function1文件已经在暂存区中等待提交。

然后我们再次对function1文件进行功能行的修改。假设添加新的功能。然后查看状态可以看到:

[html] view plaincopy
  1. watkins@watkins:~/watkins/finance$ git status   
  2. # On branch master  
  3. Changes to be committed:  
  4. #   (use "git reset HEAD <file>..." to unstage)  
  5. #  
  6. #   new file:   funciton1  
  7. #  
  8. Changes not staged for commit:  
  9. #   (use "git add <file>..." to update what will be committed)  
  10. #   (use "git checkout -- <file>..." to discard changes in working directory)  
  11. #  
  12. #   modified:   funciton1  
  13. #   

这个时候,function1 出现了两次,第一次的出现是因为我们在第一次创建文件的时候已经把文件放入到了暂存区,所以等待提交第二次出现是因为我们修改了文件,但是没有放入到暂存区,可以看到第二次的提示是:changes not staged for commit,就是说已经修改的文件还没有放入暂存区,也不会作为下一次提交的内容。


这个时候如果提交当前项目,那么提交的是第一次修改的function1 中的内容第二次修改的内容会在下一次提交的时候进入暂存区后进行提交。

这个时候如果想把第二次修改的内容也一起提交,需要使用git add 重新把修改了的文件加入到暂存区中。

[html] view plaincopy
  1. finance$ git add funciton1  
  2. finance$ git status   
  3. # On branch master  
  4. # Changes to be committed:  
  5. #   (use "git reset HEAD <file>..." to unstage)  
  6. #  
  7. #   new file:   funciton1  
  8. #  

使用git diff命令可以清楚的查看文件的哪些地方进行了修改。git diff比较的是暂存区的文件与当前工作目录的文件的差别。

再次修改function1文件,并且不暂存。使得暂存区的数据与工作目录的不一致,然后使用git diff

[html] view plaincopy
  1. finance$ git diff  
  2. diff --git a/funciton1 b/funciton1  
  3. index f67bd21..239adee 100644  
  4. --- a/funciton1  
  5. +++ b/funciton1  
  6. @@ -7,3 +7,8 @@ int elsefunction()  
  7.  {  
  8.         // inner function  
  9.  }  
  10. +  
  11. +int thirdfunction()  
  12. +{  
  13. +       // the third function  
  14. +}    
可以看到比较出了工作目录与暂存区的差别。


使用git diff --cached可以比较在暂存区的文件与上次提交的文件之间的差别。我们对README进行简单修改。

[html] view plaincopy
  1. finance$ vim README   
  2. finance$ git status   
  3. # On branch master  
  4. # Changes to be committed:  
  5. #   (use "git reset HEAD <file>..." to unstage)  
  6. #  
  7. #   new file:   funciton1  
  8. #  
  9. # Changes not staged for commit:  
  10. #   (use "git add <file>..." to update what will be committed)  
  11. #   (use "git checkout -- <file>..." to discard changes in working directory)  
  12. #  
  13. #   modified:   README  
  14. #  
  15. finance$ git add README  
  16. finance$ git status   
  17. # On branch master  
  18. # Changes to be committed:  
  19. #   (use "git reset HEAD <file>..." to unstage)  
  20. #  
  21. #   modified:   README  
  22. #   new file:   funciton1  
  23. #     
然后加入README到暂存区,比较当前暂存区与上次提交的README之间的差别

[html] view plaincopy
  1. finance$ git diff --cached   
  2. diff --git a/README b/README  
  3. index 50cf244..e5ea8ca 100644  
  4. --- a/README  
  5. +++ b/README  
  6. @@ -1,3 +1,5 @@  
  7.  this is a project that contain a software that calcualte the revenue of a company.  
  8.  and this software may have several versions.  
  9.  by watkins.song  
  10. +another revise by watkins  
  11. +hah.~~~&)(*  
  12. diff --git a/funciton1 b/funciton1  
  13. new file mode 100644  
  14. index 0000000..239adee  
  15. --- /dev/null  
  16. +++ b/funciton1  
  17. @@ -0,0 +1,14 @@  
  18. +int function1(args[])  
  19. +{  
  20. +       // do some funciton  
  21. +}  
  22. +  
  23. +int elsefunction()  
  24. +{  
  25. +       // inner function  
  26. +}  
  27. +  
  28. +int thirdfunction()  
  29. +{  
  30. +       // the third function  
  31. +}   
包括README与function1文件的差别都列出来了。

然后提交并推送到github

[html] view plaincopy
  1. finance$ git commit -m 'add function1'  
  2. [master f2f51bd] add function1  
  3.  2 files changed, 16 insertions(+)  
  4.  create mode 100644 funciton1  
  5. watkins@watkins:~/watkins/finance$ git push origin master   
  6. To https://github.com/xxxxx/finance.git  
  7.    8c4472f..f2f51bd  master -> master  
  8.  
这个时候我们的文件的版本称为C3,相当与当前文件的快照C3,C2是C3直接父节点。

很多人会觉得暂存区的设置过于麻烦,但是要牢记,每次提交到仓库的文件都必须的在暂存区中的,又可以称为在索引中的文件,提交到仓库的文件只与在暂存区中的文件打交道。

所以必须将修改的文件提交到暂存区,如果觉得每次都提交到暂存区过于繁琐,可以使用简单的提交方法,就是越过暂存区只是少些git add 而已只要在提交的时候,给 git commit 加上 -a 选项,Git 就会自动把所有已经跟踪过的文件暂存起来一并提交,从而跳过 git add 步骤

$ git commit -a -m 'added new benchmarks'

-------------------------------------------------------------------------------------------------------

4★★★★★★★
 

首先查看一下我们当前项目的提交历史,可以使用git log      

$ git log
[html] view plaincopy
  1. D:\githubSpace\FinanceProject\finance [master +2 ~0 -0 !]> git log
    commit 856907948df72d58ef0ef2d263566c43cdc0edcf
    Author: pandajava <99100963@qq.com>
    Date:   Sat Dec 20 21:22:26 2014 +0800

        add function1

    commit c88b07f7c4f739bfc426925d3162ad357f569c87
    Author: pandajava <99100963@qq.com>
    Date:   Sat Dec 20 20:57:14 2014 +0800

        add configuration file pjm

    commit 3c2257fea8bdb44e9146c08bcbcb491724f596d2
    Author: pandajava <99100963@qq.com>
    Date:   Sat Dec 20 20:07:42 2014 +0800

        my first commit From pjm

可以看到现在有三次提交。至于git log的其他的带参数的详细用法,请自己参考其他资料或者手册。

当然也可以使用git的图形工具gitk命令图形显示当前的版本提交信息。


git reset --hard  commitId:彻底回退到某个版本,本地的源码也会变为上一个版本的内容(既可以回到过去 也可以回到现在)

git  reflog


下面我们再次修改function1,function2两个文件,看看怎么取消文件的暂存和文件的修改。

[html] view plaincopy
  1. finance$ git status   
  2. # On branch master  
  3. # Changes not staged for commit:  
  4. #   (use "git add <file>..." to update what will be committed)  
  5. #   (use "git checkout -- <file>..." to discard changes in working directory)  
  6. #  
  7. #   modified:   funciton1  
  8. #   modified:   funciton2  
  9. #  
  10. no changes added to commit (use "git add" and/or "git commit -a")  
[html] view plaincopy
  1. finance$ git status   
  2. # On branch master  
  3. # Changes to be committed:  
  4. #   (use "git reset HEAD <file>..." to unstage)  
  5. #  
  6. #   modified:   funciton1  
  7. #  
  8. # Changes not staged for commit:  
  9. #   (use "git add <file>..." to update what will be committed)  
  10. #   (use "git checkout -- <file>..." to discard changes in working directory)  
  11. #  
  12. #   modified:   funciton2  
  13. #  
从上面中可以看到function1已经在暂存区中,根据提示取消暂存

[html] view plaincopy
  1. finance$ git reset HEAD funciton1  
  2. Unstaged changes after reset:  
  3. M   funciton1  
  4. M   funciton2    
如果觉得function2的修改没有必要,可以取消文件的修改,回到修改之前的状态。根据提示取消文件的修改

[html] view plaincopy
  1. finance$ git checkout -- funciton2  
然后查看文件,确实已经恢复到修改之前的代码样子。

----------------------------------------------------------------------------------------

github常用命令

git push origin master //把本地源码库push到Github上git pull origin master //从Github上pull到本地源码库git config --list //查看配置信息git status //查看项目状态信息git branch //查看项目分支git checkout -b host//添加一个名为host的分支git checkout master //切换到主干git merge host //合并分支host到主干git branch -d host //删除分支host






0 0
原创粉丝点击