Git 学习笔记(入门教程)

一.git基础

环境声明:本人用的是ubuntu14.04的系统,所以本文内容均基于该平台

本文是学习Git教程 廖雪峰 时的一些笔记。想深学习的可以查看原文。

转载请注明出处

0x01 简介

网上有很多关于git的起源,简介,用途,这里就不多数了(或许是我不知道。。。)

0x02 安装

sudo apt-get install git-core

0x03 用户配置

git是分布式版本控制系统,所以每次提交时需要一个用户名,让人知道是谁提交的。
还需要提供一个邮箱,出了问题让别人能够联系到你。

git config --global user.name "Your Name"
git config --global user.email "Your Email"

需要注意的是,config –global 参数是指在本台计算机中的所有仓库都使用该配置当然你也可以给每个仓库都配置一个name和email

0x04 创建仓库

创建一个新的文件夹,虽然也可以用不空的文件,但是出了问题不要找我
路径不要出现空格,中文,特殊字符

mkdir learnGit
cd learnGit
git init

看到下面的显示说明你成功了

Initialized empty Git repository in /home/woody/Documents/learnGit/.git/

需要注意的是,成功后会多出一个.git的文件夹,在没有必须打开的情况下
强烈不建议打开这个文件夹

0x05 添加文件

友情提示:创建的文件尽量使用utf-8的编码,Windows下的同学尽量不要使用记事本编辑,推荐sublime
在当前文件夹下创建一个readme.txt文件,随便写点东西比如

hello git

然后保存

使用下面的命令可以查看当前仓库的状态

git status

显示结果:

On branch master

Initial commit

Untracked files:
  (use "git add <file>..." to include in what will be committed)

        readme.txt

        nothing added to commit but untracked files present (use "git add" to track)

意思就是说,你修改了一个文件,但是还没有提交。
使用下面的命令添加到仓库

git add readme.txt

注意这仅仅是添加到仓库了,告诉git,这个文件是需要版本控制的。但是还没有提交。
使用下面的命令提交到仓库

git commit -m "创建readme.txt文件"

-m 的参数是对这次提交的一次说明
显示结果:

[master (root-commit) 3eb5f77] 创建readme.txt文件
 1 file changed, 1 insertion(+)
  create mode 100644 readme.txt

注意:虽然-m参数是可选的额,但是强烈建议你添加上,因为默认的配置是不添加-m参数是没有办法提交的

0x06 时光倒流(版本回退)

我想大部分同学使用git的最初的动力就是因为这个功能吧。

现在我们对readme文件进行修改,再随便添加些东西,然后readme内容就变成下面这样

hello git
hello git 2.0

然后再次add commit。

现在我们的仓库里有两个版本了,我们可以用下面的命令查看git的提交历史

git log

显示结果

commit b5934a2d9f80d257ca50b9b80a4b31d5bb9fe03c
Author: = <woody@gmail.com>
Date:   Sun Jan 22 16:27:59 2017 +0800

    第二次提交

commit 3eb5f7721cb86c617faf0d2ad13a5cee9d1a3764
Author: = <woody@gmail.com>
Date:   Sun Jan 22 16:16:10 2017 +0800

创建readme.txt文件

注意:commit字段是自动生成的,所以你的结果一定与我的不一样,以你的为准

好了,下面下面我们将readme.txt回退到最开始创建的状态。git使用HEAD表示当前的版本,就是最新的版本。
上一个版本是HEAD^,再上一个版本是HEAD^^,上一百个版本是HEAD~100(当然你也可以打100个^)。
使用下面的命令回退到指定版本

git reset --hard HEAD^
HEAD is now at 3eb5f77 创建readme.txt文件

看看内容改了没有。
现在我们再查看下log,结果如下:

commit 3eb5f7721cb86c617faf0d2ad13a5cee9d1a3764
Author: = <coder.0012ff7c@gmail.com>
Date:   Sun Jan 22 16:16:10 2017 +0800

    创建readme.txt文件

好了,时光倒流成功!但是悲哀的发现我们回不到未来了。还是有办法的,–hard 参数支持commit值。
就是说你可以在–hard后面跟一个commit值,就能跳到那个版本。
执行下面的代码

git reset --hard b5934a
HEAD is now at b5934a2 第二次提交

不用将所有的字符都写上,只要能区分出不同就好,git会自动去匹配

但是万一找不到commit值呢,没关系。使用下面的命令可以查看所有的历史

git reflog

显示结果:

b5934a2 HEAD@{0}: reset: moving to b5934a
3eb5f77 HEAD@{1}: reset: moving to HEAD^
b5934a2 HEAD@{2}: commit: 第二次提交
3eb5f77 HEAD@{3}: commit (initial): 创建readme.txt文件

最前面那串字符就是。好了。搞定!

0x07 工作区,暂存区,版本库

工作区:就是指当前的目录,比如我们创建的learnGit目录
暂存区:通过git add 命令将文件添加到暂存区。
版本库:就是指创建仓库时自动生成的那个.git目录,也是强烈建议不要乱动的目录。
git中的文件必须先添加到暂存区,然后才能添加到版本库。

重新创建一个文件Hello.java,随便写点内容比如

hello java

然后再修改下readme文件,添加一行

添加 hello.java 文件 

然后查看下仓库状态

git status

显示结果:

On branch 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:   readme.txt

      Untracked files:
  (use "git add <file>..." to include in what will be committed)

      Hello.java

no changes added to commit (use "git add" and/or "git commit -a")

说明readme.txt被修改了,而hello.java还没有被添加到仓库。
然后我们将这两个文件添加到暂存区

git add readme.txt
git add Hello.java

你也可以使用下面的命令将当前文件夹下的所有文件都添加到暂存区
git add –all

再查看下状态显示结果:

On branch master
Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)

      new file:   Hello.java
      modified:   readme.txt

然后再用commit命令添加到版本库
git commit -m “添加Hello.java文件”
再查看下状态显示结果为

On branch master
nothing to commit, working tree clean

0x08 撤销修改

1.仅仅是修改了工作区,并没有add到暂存区

我们对Hello.java做一些修改,如下:

public class Hello{
    public static void main(String[] args){

    }
}

如果这个时候我们需要回到上一个版本,当然,你可以手动的修改Hello.java文件。
但是要是万一你哪里再记错了,就尴尬了。
查看一下状态

git status
On branch 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:   Hello.java

no changes added to commit (use "git add" and/or "git commit -a")

git告诉你说,使用 git checkout – … 可以放弃当前工作区的修改。试一下,

git checkout Hello.java 

查看下Hello.java 文件,是不是恢复了。

2.不仅仅修改了工作区,而且还add到了暂存区。

我们对Hello.java再次做一些修改,如下:

public class Hello{
    public static void main(String[] args){

    }
}

然后add到暂存区

git add Hello.java

查看一下状态

On branch master
Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)

    modified:   Hello.java

git告诉你说,使用 git reset HEAD … 可以撤销缓存。然后我们尝试一下

git reset HEAD Hello.java

运行结果

Unstaged changes after reset:
M   Hello.java

查看一下状态

On branch 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:   Hello.java

no changes added to commit (use "git add" and/or "git commit -a")

是不是又回到第一种的状态了。

3. 不仅仅修改了工作区,还add到了暂存区,而且手贱的我还commit到了版本库。

如果你目前还没有推送到远程仓库,还有的救,还记得上面说的时光倒流么。不记得的可以翻一翻。

git reset --hard HEAD^

这样就回到了第二种情况。

0x09 文件删除

在仓库里新建一个文件,然后添加到版本库

git add test.txt
git commit -m "add test.txt"

然后我们将这个文件删除掉。

rm test.txt

查看一下状态

On branch master
Changes not staged for commit:
  (use "git add/rm <file>..." to update what will be committed)
  (use "git checkout -- <file>..." to discard changes in working directory)

    deleted:    test.txt

no changes added to commit (use "git add" and/or "git commit -a")

git 检测到有文件被删除了,git告诉你有两种方式
1. git rm … :从版本库删除文件,并重新commit
2. 撤销删除操作,test.txt将被恢复。

使用下面的命令从版本库删除文件。

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

小结:通过以上的学习我们已经可以熟练的操作本地的git仓库了。


二. git远程仓库

0x01 创建远程仓库

git是分布式版本控制系统。分布式,即最开始仅有一个仓库作为服务器,然后其他人从这个仓库克隆出代码,提交到这个仓库,
每个克隆的仓库都可以是一个服务器,各个仓库之间没有主次之分。

要学习远程仓库,首先得有个远程仓库,由于搭建远程git仓库有(本)点(人)复(不)杂(会)。这里使用github作为远程仓库

由于之前写过类似的,这里不再赘述。

需要注意的是,在创建仓库是使用learnGit作为仓库名

在github创建远程仓库

你只需做到使用下面的命令测试成功就好

ssh -v [email protected] 

0x02 推送到远程仓库

将本地仓库与远程仓库关联,在本地仓库目录下执行下面的命令。

git remote add origin [email protected]:coderRan/learnGit.git

**注意:[email protected]:coderRan/learnGit.git一定是你自己的创建的仓库,不要复制我的,
因为这是我的仓库,关联不会出问题,推送的时候你是推送不上去的,因为我的github没有添加你的ssh key**

现在仅仅是关联起来了,还没有将代码推送到远程仓库,执行下面的命令

git push -u origin master

要是没有出现下面的结果请看0x03

上传文件是需要时间的,所以要耐心等待一下。执行结果

Counting objects: 16, done.
Delta compression using up to 4 threads.
Compressing objects: 100% (9/9), done.
Writing objects: 100% (16/16), 1.29 KiB | 0 bytes/s, done.
Total 16 (delta 1), reused 0 (delta 0)
remote: Resolving deltas: 100% (1/1), done.
To github.com:coderRan/learnGit.git
 * [new branch]      master -> master
Branch master set up to track remote branch master from origin.

去你刚才创建的仓库看一下,应该上传上去了。

第一次推送有点麻烦,因为git需要将本地仓库的分支与远程仓库的分支进行关联。以后推送的话可以使用下面的命令

git push origin master

0x03 SSH警告

在第一次使用 push 或者 clone 这个命令时,会弹出一个警告

The authenticity of host 'github.com (xx.xx.xx.xx)' can't be established.
RSA key fingerprint is xx.xx.xx.xx.xx.
Are you sure you want to continue connecting (yes/no)?

这个是SSH链接需要你确认ssh key。
输入yes,结果

Warning: Permanently added 'github.com' (RSA) to the list of known hosts.

这些警告只出现在第一次提交时,以后就不会出来了。

0x04 从远程仓库克隆

新建一个 目录
mkdir newGit
cd newGit
然后从我们刚刚新建的仓库克隆一个

git clone [email protected]:coderRan/learnGit.git

执行结果:

Cloning into 'learnGit'...
remote: Counting objects: 16, done.
remote: Compressing objects: 100% (8/8), done.
remote: Total 16 (delta 1), reused 16 (delta 1), pack-reused 0
Receiving objects: 100% (16/16), done.
Resolving deltas: 100% (1/1), done.

三.git 分支

0x01 分支简介

分支是什么呢?
你可以理解成树枝。
分支可以用来干什么呢?
使用分支意味着你可以把你的工作从开发主线上分离开来,以免影响开发主线。

假如,你开发了一个支付宝,然后想添加一个扫福的功能,你总不能直接在你的版本库里乱改吧,这个版本正常用着呢,万一改错,不能用了就麻烦了。话说不是有clone么,克隆一份就好了,再怎么改也不会出问题,但是,你在开发过程中,完成一部分工作后总得提交到远程仓库吧。(有人说,不用提交啊,自己在本地仓库搞就好了。注意,协同作业)

这个时候就用到分支了。把仓库看成一棵树,随着一次次的commit,这棵树越长越高,分支就向树枝一样。在分支上可以随便撒野,不会搞坏主分支。你可以把你的修改先提交到自己创建的分支上,等你把这个扫福的功能开发完了,还能合并到主分支上。

0x02 分支的创建

在我们创建好仓库后,版本库的状态是下面这样的,其中的[A],[B],[C] 代表一个commit

  HEAD->master-->|
                 |
    [A]-->[B]-->[C] 

其中 master 代表的是主分支,而HEAD代表的是当前分支,由于只有一个分支所以HEAD指向的是 master
我们使用下面的命令创建一个分支,然后切换到新建的分支。

git branch mybranch
git checkout mybranch

你也可以使用一条命令,创建并切换

git checkout -b mybranch

查看下分支

git branch
  master
* mybranch

现在git仓库的状态是下面这样的

    master-->|
             |
[A]-->[B]-->[C] 
             |
             |<--mybranch<--HEAD

然后我们再次对Hello.java文件做一下修改

public class Hello{
    public static void main(String[] args){

    }
    public void addBranch(){

    }
}    

然后commit到版本库

0x03 分支的合并

现在git仓库的状态是下面这样的

    master-->|
             |
[A]-->[B]-->[C]~~>[D] 
                   |
                   |<--mybranch<--HEAD

然后切换到 master 分支

git checkout master

现在git仓库的状态是下面这样的

 HEAD-->master-->|
                 |
    [A]-->[B]-->[C]~~>[D] 
                       |
                       |<--mybranch

合并到 master 分支

git merge mybranch 

执行结果

Updating 28c1cc8..11d62a7
Fast-forward
 Hello.java | 3 +++
 1 files changed, 3 insertions(+)

现在git仓库的状态是下面这样的

   HEAD-->master-->|
                   |
[A]-->[B]-->[C]~~>[D] 
                   |
                   |<--mybranch

0x04 分支的删除

git branch -d mybranch

0x05 解决冲突

快速合并的速度确实很快,但是前提是两个分支没有冲突。

重新创建新的分支

git checkout -b newbranch

修改 readme.txt 文件

hello git
hello git 2.0
添加 hello.java 文件
在 newbranch 分支上做的修改    

提交

git add readme.txt 
git commit -m "newbranch 修改"

[newbranch b8ac4ad] newbranch 修改
 1 file changed, 1 insertion(+)

切换到 master 分支

git checkout master

打开 readme.txt 文件,发现并没有改变,因为我们的修改不是在master分支上的。

添加一行

hello git
hello git 2.0
添加 hello.java 文件
在 master 分支上做的修改

提交

git add readme.txt 
git commit -m "master 修改"

[master 80c56bf] master 修改
 1 file changed, 1 insertion(+)

现在 两个分支上对一个文件的同一个地方(同一行)做了不同的修改,是没办法快速合并的。

合并下试试

git merge newbranch

git merge newbranch 
Auto-merging readme.txt
CONFLICT (content): Merge conflict in readme.txt
Automatic merge failed; fix conflicts and then commit the result.

果然,git说, readme.txt 文件冲突了,修复后重新提交。
使用 git status 看看状态

git status

On branch master
Your branch is ahead of 'origin/master' by 3 commits.
  (use "git push" to publish your local commits)
You have unmerged paths.
  (fix conflicts and run "git commit")
  (use "git merge --abort" to abort the merge)

Unmerged paths:
  (use "git add <file>..." to mark resolution)

    both modified:   readme.txt

no changes added to commit (use "git add" and/or "git commit -a")

git说 对 readme.txt 共同的两个修改

我们直接打开 readme.txt 文件看看

hello git
hello git 2.0
添加 hello.java 文件
<<<<<<< HEAD
在 master 分支上做的修改
=======
在 newbranch 分支进行修改
>>>>>>> newbranch

其中 <<<,===,>>>是分割线。
我们修改一下

hello git
hello git 2.0
添加 hello.java 文件
修复了冲突

然后提交
git add readme.txt
git commit -m “修复了冲突”

[master 9f1e5f5] 修复了冲突

好了,解决。现在git已经将两个分支自动合并了。你可以使用

git log --graph

查看分支图

然后删除 newbranch 分支

git branch -d newbranch 
Deleted branch newbranch (was b8ac4ad).

0x06 合并的方式选择

从上面我们知道,分支的合并有两种方式,一种是 快速合并,一种是解决冲突的合并。

两种合并的区别是

快速合并要保证没有冲突,合并完删除分支后,会丢掉分支信息。
冲突合并会保留分支信息,Git会在merge时生成一个新的commit。

可以使用--no-ff参数强制禁用快速合并

git merge --no-ff -m "禁用快速合并" newbranch

因为需要重新生成一个 commit 所以需要添加-m参数。

四.git tag

有时我们需要定位到某个版本,但是目前我们只能通过那个长长的commit号来确定。
为了更好的定位,我们可以给commit 打个tag。

0x01 默认在最新的commit上打tag

git tag v1.0

0x02 对任意commit打tag

找到commit号(还记得怎么看commitid号么?)

git tag v0.9 <commitid>

0x03 查看tag

需要注意的是,tag是按字母排序的额,不是按时间排序的

git tag

0x04 查看tag信息

git show <tagname>

0x04 删除tag

git tag -d <tagname>

0x05 操作远程仓库的tag

因为tag默认是存储到本地的,所以需要手动将tag推送到远程仓库

git push origin <tagname>

如果tag比较多,可以一次将所有tag都推送到远程仓库

git push origin --tags

如果你已经将tag推送到远程仓库了,再想删除就有点麻烦了。
首先需要删除本地的tag

git tag -d <tagname>

然后再删除远程仓库的tag

git push origin :refs/tags/<tagname>

五.github

github的使用

根据上面的文章配置好github,就可以按照远程仓库的操作提交代码到github上了。

猜你喜欢

转载自blog.csdn.net/u013451048/article/details/58183671