Git使用入门

来源:互联网 发布:图画软件下载 编辑:程序博客网 时间:2024/05/18 21:41


      

      Git命令是一些命令行工具的集合,它可以用来跟踪,记录文件的变动。比如你可以进行保存、比对、分析、合并等。Git是分布式的,这意味着它并不依赖于中心服务器,任何一台机器都可以有一个本地版本的控制系统,我们称之为仓库。如果是多人协作的话,你需要一个线上仓库,用来同步信息。这就是GitHub, BitBucket的工作。


1.安装Git

Linux(Ubuntu):

$ sudo apt-get install git-all

Windows:
推荐使用git for windows,它包括了图形工具以及命令行模拟器。

OS X:

$ brew install git

2.配置Git

安装完git,首要任务是配置我们的信息,最重要的是用户名及邮箱,打开终端,执行以下命令。

$ git config --global user.name "myName"$ git config --global user.email "myEmail@example.com"

3.创建一个新仓库 - git init

git 会把所有文件以及历史记录保存在你的项目中,创建一个新的仓库,首先要去到项目路径,执行 git init。然后git会创建一个隐藏的文件 .git,所有的信息都储存在其中。

在Documents创建一个联系文件夹 GitDemo, 新建一个 demo.c 文件,打开终端:

$ cd Documents/~/Documents$ mkdir GitDemo~/Documents$ git initInitialized empty Git repository in /home/hongwei/Documents/GitDemo/.git/ #(提示多了一个.git文件)~/Documents$ cd GitDemo/~/Documents/GitDemo$ vim demo.c#include<stdio.h>int main(){        printf("Hello World!\n");        return 0;}
Esc,shift+:wq保存退出

4.检查状态 - git status

git status 会告诉我们创库的当前状态:是否为最新代码,有什么更新等

执行git status

~/Documents/GitDemo$ git statusOn branch masterInitial commitUntracked files:  (use "git add <file>..." to include in what will be committed)demo.cnothing added to commit but untracked files present (use "git add" to track)
git 告诉我们,demo.c尚未跟踪,这是因为这个文件是新的,git不知道是应该跟踪它的变动呢,还是直接忽略不管呢。为了跟踪我们的新文件,我们需要暂存它。

5.暂存 - git add

git 有个概念叫 暂存区,可以包含所有你可能会提交的变动。它一开始为空,你可以通过 git add 命令添加内容,并使用 git commit 提交。

这个例子中只有一个文件:

$ git add demo.c
如果需要提交目录下的所有内容,执行指令:

$ git add-A
再次执行Git status查看:

~/Documents/GitDemo$ git add demo.c ~/Documents/GitDemo$ git statusOn branch masterInitial commitChanges to be committed:  (use "git rm --cached <file>..." to unstage)new file:   demo.c
我们的文件已经提交了。状态信息还会告诉我们暂存区文件发生了什么变动,不过这里我们提交的是一个全新文件。

6.提交 - git commit

创建提交,需要我们提交东西到暂存区(git add),然后:

~/Documents/GitDemo$ git commit -m "First Commit"<pre name="code" class="plain">[master (root-commit) 08ac0ca] First Commit 1 file changed, 6 insertions(+) create mode 100644 demo.c
这就创建了一次提交,-m “First Commit.”表示对这次提交的描述,建议使用有意义的描述性信息。

远端仓库

到目前为止,我们的操作都是在本地的,它存在于.git文件中。为了能够协同开发,我们需要把代码发布到远端仓库上。

1.创建远端仓库

登录Github账户,点击上方导航栏的+按钮,选择“New repository”

进入到创建界面,填写Repository name,Description等信息,最后Create Repository

点击CreateRepository后,查看远端仓库的地址

2.链接远端仓库 - git remote add

添加测试用的远端仓库:

$ git remote add origin https://github.com/Grand2015/GithubTest.git

一个项目可以同时拥有好几个远端仓库为了能够区分,通常会起不同的名字。通常主远端仓库被称为origin。

3.上传到服务器 - git push

每次我们要提交代码到服务器上时,都会使用到git push。

git push命令会有两个参数,远端仓库的名字,以及分支的名字:

~/Documents/GitDemo/GithubTest$ git push origin master<pre name="code" class="plain">Username for 'https://github.com': Grand2015Password for 'https://Grand2015@github.com': Counting objects: 4, done.Compressing objects: 100% (3/3), done.Writing objects: 100% (3/3), 338 bytes | 0 bytes/s, done.Total 3 (delta 0), reused 0 (delta 0)To https://github.com/Grand2015/GithubTest.git   cea07c5..6a143dc  master -> master

取决于你使用的服务器,push过程你可能需要验证身份。如果没有出差错,现在使用浏览器去你的远端分支上看,demo.c已经在那里等着你了。

4.克隆仓库 - git clone

放在Github上的开源项目,人们可以看到你的代码。可以使用 git clone进行下载到本地。

$ git clone https://github.com/Grand2015/GithubTest.gitCloning into 'GithubTest'...remote: Counting objects: 3, done.remote: Total 3 (delta 0), reused 0 (delta 0), pack-reused 0Unpacking objects: 100% (3/3), done.Checking connectivity... done.

本地也会创建一个新的仓库,并自动将github上的分支设为远端分支。

5.从服务器上拉取代码 - git pull

如果你更新了代码到仓库上,其他人可以通过git pull命令拉取你的变动:

$ git pull origin masterFrom https://github.com/Grand2015/GithubTest * branch            master     -> FETCH_HEADAlready up-to-date.

因为暂时没有其他人提交,所有没有任何变动


分支

1467123600214507.jpg

branchs

当你在做一个新功能的时候,最好是在一个独立的区域上开发,通常称之为分支。分支之间相互独立,并且拥有自己的历史记录。这样做的原因是:

  • 稳定版本的代码不会被破坏

  • 不同的功能可以由不同开发者同时开发。

  • 开发者可以专注于自己的分支,不用担心被其他人破坏了环境

  • 在不确定之前,同一个特性可以拥有几个版本,便于比较

1.创建新分支 - git branch

每一个仓库的默认分支都叫master, 创建新分支可以这样:

~/Documents/GithubTest$ git branch NewBranch

创建了一个名为amazing_new_feature的新分支,它跟当前分支同一起点

2.切换分支 - git checkout

使用git branch,可以查看分支状态:

~/Documents/GithubTest$ git branch   NewBranch* master

* 号表示当前活跃分支为master,使用git checkout切换分支。
~/Documents/GithubTest$ git checkout NewBranch Switched to branch 'NewBranch'

3.合并分支 - git merge

我们的 NewBranch 分支的任务是增加一个新分支加入的显示打印任务。我们编辑,添加到暂存区,提交。

代码变成如下状态:

$ cat -n demo.c      1#include<stdio.h>     2int main()     3{     4printf("Hello World\n");     5printf("A NewBranch was added!");     6return 0;     7}

我们还可以查看具体的改变:

~/Documents/GithubTest$ git diff --cached~/Documents/GithubTest$ git diffdiff --git a/demo.c b/demo.cindex 36f7b59..a4ddd4e 100644--- a/demo.c+++ b/demo.c@@ -2,5 +2,6 @@ int main() {        printf("Hello World\n");+       printf("A NewBranch was added!");        return 0; }

git diff --cached是产看两次代码的改变情况,git diff 输出 改变情况。

(git diff --cached比较git add和git commit之间的区别,而git diff是比较暂存区的文件和暂存区之间的区别,灵活运用)

紧接着add和commit,中间可以使用git status指令来查看文件提交的状态:

~/Documents/GithubTest$ git statusOn branch NewBranchChanges not staged for commit:  (use "git add <file>..." to update what will be committed)  (use "git checkout -- <file>..." to discard changes in working directory)modified:   demo.cno changes added to commit (use "git add" and/or "git commit -a")~/Documents/GithubTest$ git add demo.c ~/Documents/GithubTest$ git statusOn branch NewBranchChanges to be committed:  (use "git reset HEAD <file>..." to unstage)modified:   demo.c~/Documents/GithubTest$ git commit -m "New Branch"[NewBranch a1a7828] New Branch 1 file changed, 1 insertion(+)

新分支任务完成了,回到master分支

$ git checkout masterSwitched to branch 'master'Your branch is up-to-date with 'origin/master'.

现在去查看代码

~/Documents/GithubTest$ cat -n demo.c      1#include<stdio.h>     2int main()     3{     4printf("Hello World\n");     5return 0;     6}

细心的朋友看到,我们刚才加入的显示加入新的分支的打印指令并没有。对的,没有就是对的,这就是分支branch的独立开发,虽然在分支上做了改变,如果我们没有执行master和branch融合指令之前,master上的代码还是原来的代码。

下面是不是要融合了呢?

不,如果就这么简单的融合了,那就太便宜这个例子了,我们下面在对master的代码在做一点改变,添加一个版本号的打印指令:

~/Documents/GithubTest$ git diffdiff --git a/demo.c b/demo.cindex 36f7b59..6d05ca1 100644--- a/demo.c+++ b/demo.c@@ -2,5 +2,6 @@ int main() {        printf("Hello World\n");+       printf("Version:1.0");        return 0; }~/Documents/GithubTest$ git statusOn branch masterYour branch is up-to-date with 'origin/master'.Changes not staged for commit:  (use "git add <file>..." to update what will be committed)  (use "git checkout -- <file>..." to discard changes in working directory)modified:   demo.cno changes added to commit (use "git add" and/or "git commit -a")~/Documents/GithubTest$ git add demo.c ~/Documents/GithubTest$ git statusOn branch masterYour branch is up-to-date with 'origin/master'.Changes to be committed:  (use "git reset HEAD <file>..." to unstage)modified:   demo.c~/Documents/GithubTest$ git commit -m "Add Version"[master 3b480dd] Add Version 1 file changed, 1 insertion(+)

好了,现在branch和master都作了修改,现在开始融合。

~/Documents/GithubTest$ git merge NewBranch Auto-merging demo.cCONFLICT (content): Merge conflict in demo.cAutomatic merge failed; fix conflicts and then commit the result.

你会发现有融合失败的提示automatic merge failed并且还有conflicts,ok,这就是我们要解决的另一个问题,代码融合时出现冲突怎么办?

执行指令cat demo.c查看问题

~/Documents/GithubTest$ cat demo.c #include<stdio.h>int main(){printf("Hello World\n");<<<<<<< HEADprintf("Version:1.0");=======printf("A NewBranch was added!");>>>>>>> NewBranchreturn 0;}

<<<<<<<表示master上改变的地方

>>>>>>>表示branch上改变的地方

=======表示master和branch的分割线

那面就进入代码中修改好了,想要的保留,不想要的删掉

$ cat demo.c #include<stdio.h>int main(){printf("Hello World\n");printf("Version:1.0");printf("A NewBranch was added!");return 0;}

好的,接下来我们再提交一下

~/Documents/GithubTest$ git add demo.c ~/Documents/GithubTest$ git commit -m "Merge confilcts"[master 3e508c3] Merge confilcts

ok! 然后再把NewBranch分支删掉吧。

~/Documents/GithubTest$ git branch -d NewBranch Deleted branch NewBranch (was a1a7828).

高级

这篇文章的最后一节,我们来说些比较高级并且使用的技巧。

1.比对两个不同提交之间的差别

每次提交都有一个唯一id,查看所有提交和他们的id,可以使用 git log:

~/Documents/GithubTest$ git logcommit 3e508c3bff0ce6dd79d360f68bbb2dbfc3e4df7bMerge: 3b480dd a1a7828Author: Grand2015 <997812940@qq.com>Date:   Wed Jul 20 19:19:27 2016 +0800    Merge confilctscommit 3b480ddb802c4eaf86cf6252be1774b507859846Author: Grand2015 <997812940@qq.com>Date:   Wed Jul 20 18:57:29 2016 +0800    Add Versioncommit a1a782894b7f3c944ffa21f34bbb54f723ac3097Author: Grand2015 <997812940@qq.com>Date:   Wed Jul 20 18:39:26 2016 +0800    New Branchcommit 6a143dcf25c67ca7d2c4609ef7745c178ed11133Author: Grand2015 <997812940@qq.com>Date:   Tue Jul 19 02:32:13 2016 -0700    First Commitcommit cea07c59d127590dee621b695c7dd169523b3bedAuthor: Grand Li <997812940@qq.com>Date:   Tue Jul 19 17:44:04 2016 +0800    Delete hello.txtcommit 7627f852cf143e49414067df499aa780d0bb78ffAuthor: Grand2015 <997812940@qq.com>Date:   Sun Jul 17 22:33:03 2016 +0800    new documentcommit 3fa2685cefadd18fda59971fa9f5c30d157d66c5Author: Grand Li <997812940@qq.com>Date:   Sun Jul 17 21:49:12 2016 +0800    Initial commit

id 很长,但是你并不需要复制整个字符串,前一小部分就够了。

查看某一次提交更新了什么,使用 git show:

$ git show 3e508c3bff0ce6dd79d360f68bbb2dbfc3e4df7bcommit 3e508c3bff0ce6dd79d360f68bbb2dbfc3e4df7bMerge: 3b480dd a1a7828Author: Grand2015 <997812940@qq.com>Date:   Wed Jul 20 19:19:27 2016 +0800    Merge confilctsdiff --cc demo.cindex 6d05ca1,a4ddd4e..eaf69b0--- a/demo.c+++ b/demo.c@@@ -2,6 -2,6 +2,7 @@@  int main()  {        printf("Hello World\n"); +      printf("Version:1.0");+       printf("A NewBranch was added!");        return 0;  }

查看两次提交的不同,可以使用git diff [commit-from]..[commit-to] 语法:

比较首次提交和最后一次提交,我们可以看到所有的更改。当然使用git difftool命令更加方便。

2.回滚某个文件到之前的版本

git 允许我们将某个特定的文件回滚到特定的提交,使用的也是 git checkout。

下面的例子,我们将demo.c回滚到最初的状态,需要指定回滚到哪个提交,以及文件的全路径。

$ git checkout 3e508c3bff0ce6dd79d360f68bbb2dbfc3e4df7b demo.c

3.回滚提交

如果你发现最新的一次提交完了加某个文件,你可以通过 git commit —amend来修复,它会把最新的提交打回暂存区,并尝试重新提交。

如果是更复杂的情况,比如不是最新的提交了。那你可以使用git revert。

最新的一次提交别名也叫HEAD。

$ git revert HEAD

其他提交可以使用id:


$ git revert 3e508c3bff0ce6dd79d360f68bbb2dbfc3e4df7b

混滚提交时,发生冲突是非常频繁的。当文件被后面的提交修改了以后,git不能正确回滚。

4.配置 .gitignore

大部分项目中,会有写文件,文件夹是我们不想提交的。为了防止一不小心提交,我们需要gitignore文件:

  • 在项目根目录创建.gitignore文件

  • 在文件中列出不需要提交的文件名,文件夹名,每个一行

  • .gitignore文件需要提交,就像普通文件一样

通常会被ignore的文件有:

  • log文件

  • task runner builds

  • node_modules等文件夹

  • IDEs生成的文件

  • 个人笔记


1 0