Git基本概念

在一个普通的文件夹下使用git init命令就会创建一个.git文件夹,原来的文件夹就变成了一个git repository。关于repository所有的变动都记录在这个.git文件夹中,所以.git文件夹就是git repository和普通文件夹的唯一区别。把它删除了,git repository也就变成了普通文件夹。

git中,提交一次操作进版本库的包含两个步骤:stagingcommitting。如下图所示:

1-1

(1)Staginggit add操作。修改后的文件只是进入了staging区域,还没有进入最后的版本库。Staging中的修改会在下一次git commit操作中提交进版本库。Staging中的文件状态也被称作snapshotStaging可以使用户把相关的改动保存在一个snapshot中,这样保证每次commit都是有关联,有意义的。

(2)Committinggit commit操作。把staging区域中的snapshot提交进版本库。

另外,git status命令显示当前repository中所有文件的状态,比如哪些文件处于staging区域,git log则会显示已经进入版本库的revision history。如下图所示:

1-2

参考资料:
The Basics

git patch简介

本文简单介绍一下git patch

首先创建包含git的工作目录:

git init git_repo

接着在这个文件夹下创建一个文本文件(a.txt):

aaaa
bbbb
cccc
dddd
eeee
ffff

把这个文件加到git版本控制:

git add a.txt
git commit -m "Initialize a.txt"

接着再开出一个patch分支,剩下的操作都在这个分支上进行:

git checkout -b patch

然后把a.txt文件第二行的bbbb改成bb11

aaaa
bb11
cccc
dddd
eeee
ffff

提交:

git commit -a -m "Modify a.txt"

接下来生成相对于master分支的patch

[root@localhost git_repo]# git format-patch master
0001-Modify-a.txt.patch

看一下0001-Modify-a.txt.patch这个patch文件:

From 9512ec20468586e0632ece9e97e4e89b3a68c40e Mon Sep 17 00:00:00 2001
From: root <root@localhost.localdomain>
Date: Thu, 30 Jul 2015 02:30:45 -0400
Subject: [PATCH 1/3] Modify a.txt

---
 a.txt | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/a.txt b/a.txt
index 1707b56..1ba3da1 100644
--- a/a.txt
+++ b/a.txt
@@ -1,5 +1,5 @@
 aaaa
-bbbb
+bb11
 cccc
 dddd
 eeee
--
2.4.3

重点看一下@@ -1,5 +1,5 @@-1,5表示原来的文件,+1,5表示修改后的文件。1表示起始行号,5表示从起始行号算起,一共包含多少行。下面的-bbbb表示删除原来文件的内容,而+bb11表示修改后文件的内容。

下面切换回master分支:

[root@localhost git_repo]# git checkout master
Switched to branch 'master'

看一下master分支的a.txt

[root@localhost git_repo]# cat a.txt
aaaa
bbbb
cccc
dddd
eeee
ffff

没有任何变化。

接下来merge patch

[root@localhost git_repo]# git am < 0001-Modify-a.txt.patch
Applying: Modify a.txt

再次查看a.txt

[root@localhost git_repo]# cat a.txt
aaaa
bb11
cccc
dddd
eeee
ffff

可以看到patch已经成功地merge进了a.txt

Git clone命令笔记

git clone命令用来拷贝一个已经存在的代码仓库。Clone操作会自动创建一个指向原始代码仓库的远程连接(名字是origin),这会很方便操作中央代码库。git的合作开发模式是基于“代码仓库-代码仓库”(repository-to-repository),不同于SVN的从工作拷贝向中央代码仓库提交代码的方式,gitpushpull操作都是从一个代码仓库到另一个代码仓库。

使用:

a)git clone <repo>
把位于repo的代码仓库复制到本机。

b)git clone <repo> <directory>
把位于repo的代码仓库复制到本机的directory

例子:

[root@CentOS ~]# git clone https://github.com/sharklinux/shark
Cloning into 'shark'...
remote: Counting objects: 1003, done.
remote: Total 1003 (delta 0), reused 0 (delta 0), pack-reused 1003
Receiving objects: 100% (1003/1003), 21.43 MiB | 304.00 KiB/s, done.
Resolving deltas: 100% (245/245), done.
[root@CentOS ~]# ls
anaconda-ks.cfg  shark

执行git clone https://github.com/sharklinux/shark在本机初始化一个shark文件夹(注意没有.git后缀,表明这是一个非bare属性的本地拷贝),文件夹里包含了整个shark代码仓库的所有内容。

参考资料:
git clone

Git init命令笔记

git init命令用来创建一个新的Git仓库。它既可以用来完全初始化一个新的空仓库,也可以把一个已经存在的,没有版本控制的仓库转成Git仓库。执行git init命令会在指定工程的根目录下创建一个.git的子文件夹。除了.git子文件夹,工程的其它文件都不会改变。

使用:

a)git init
把当前目录变成一个Git仓库。

b)git init <directory>
在指定的目录下创建Git仓库。执行这个命令将会创建一个叫directory的新文件夹,在这个文件夹里只有.git子文件夹。

c)git init --bare <directory>
初始化一个没有工作文件夹的空的Git仓库。用来共享的Git仓库应该始终使用--bare选项来创建。通常情况下,用--bare选项初始化的仓库以.git作为后缀。举个例子,使用--bare选项创建的project仓库应该叫project.git

比较一下git init <directory>git init --bare <directory>
首先执行git init linux:

[root@CentOS ~]# git init linux
Initialized empty Git repository in /root/linux/.git/
[root@CentOS ~]# ls -alt linux/
total 8
dr-xr-x---. 5 root root 4096 Jun  2 12:53 ..
drwxr-xr-x. 7 root root 4096 Jun  2 12:42 .git
drwxr-xr-x. 3 root root   17 Jun  2 12:42 .
[root@CentOS ~]# ls -alt linux/.git
total 20
drwxr-xr-x. 7 root root 4096 Jun  2 12:42 .
drwxr-xr-x. 4 root root   28 Jun  2 12:42 objects
-rw-r--r--. 1 root root   92 Jun  2 12:42 config
-rw-r--r--. 1 root root   23 Jun  2 12:42 HEAD
drwxr-xr-x. 2 root root   20 Jun  2 12:42 info
drwxr-xr-x. 2 root root 4096 Jun  2 12:42 hooks
-rw-r--r--. 1 root root   73 Jun  2 12:42 description
drwxr-xr-x. 2 root root    6 Jun  2 12:42 branches
drwxr-xr-x. 3 root root   17 Jun  2 12:42 ..
drwxr-xr-x. 4 root root   29 Jun  2 12:42 refs

接着执行git init --bare bsd:

[root@CentOS ~]# git init --bare bsd
Initialized empty Git repository in /root/bsd/
[root@CentOS ~]# ls -lt bsd
total 16
drwxr-xr-x. 4 root root   28 Jun  2 13:01 objects
-rw-r--r--. 1 root root   66 Jun  2 13:01 config
drwxr-xr-x. 2 root root    6 Jun  2 13:01 branches
-rw-r--r--. 1 root root   73 Jun  2 13:01 description
-rw-r--r--. 1 root root   23 Jun  2 13:01 HEAD
drwxr-xr-x. 2 root root 4096 Jun  2 13:01 hooks
drwxr-xr-x. 2 root root   20 Jun  2 13:01 info
drwxr-xr-x. 4 root root   29 Jun  2 13:01 refs

可以看到所有的文件信息都直接创建在bsd目录下,而没有创建在.git文件夹下。

参考文档:
git init

使用gitlab docker image搭建git server

这两天折腾了一下gitlab,遇到一些问题,记录一下,以便日后查阅。

(1)gitlab使用的是docker image(下载地址:https://registry.hub.docker.com/u/genezys/gitlab/),这个比较顺利,按README操作即可。

(2)接下来,就是用git client(版本:1.8.3.1)访问git server,这个过程相当痛苦。把结论总结在这里:

a)由于gitlab container22端口会映射到宿主机的2222端口,所以需要在“~/.ssh/config”文件中加上“Port 2222”这一句;

b)使用“git clone”命令clone项目。其中repository地址可以从gitlab web页面查到。例如:“git@192.168.59.103:root/test.git”,但要注意的是需要把IP改成宿主机的IP。举例,如果宿主机IP10.137.20.113,则改为“git@10.137.20.113:root/test.git”;

c)最后需要指出的是,如果git clone命令不指定目的文件夹,则默认目的文件夹为xxx.git中的xxx。以上面命令为例,则目的文件夹为test。一定要确保目的文件夹不存在,或者里面没有内容。否则会提示“fatal: destination path 'xxx' already exists and is not an empty directory.”。

P.S. 关于git clone命令访问非标准SSH端口,也可参考我的这篇文章

参考资料:
1)How can I use git client to access gitlab docker?
2)How to get Git to clone into current directory