两本书:
Simple Git tutorial for beginners | Nulab
基础入门可以参考廖雪峰的文章;
关于相关GUI工具,官网已经提供了,
Windows:tortoise , sourcetree
ubuntu : GitAhead
git 自带的 git gui 也可以;
将 GitAhead 添加到 favorite 工具栏;
/usr/share/applications
直接参考 Cheese ,vim 打开查看,复制 修改为自己的程序;
[Desktop Entry]
Name=GitAhead
GenericName=GitAhead
X-GNOME-FullName=GitAhead
Comment=GitAhead
Keywords=GitAhead
Exec=/home/y/Desktop/program/GitAhead/GitAhead
Terminal=false
Type=Application
StartupNotify=true
Icon=/home/y/Desktop/program/GitAhead/Resources/GitAhead.iconset/icon_256x256.png
Categories=GNOME;
X-GNOME-Bugzilla-Bugzilla=GNOME
X-GNOME-Bugzilla-Product=GitAhead
X-GNOME-Bugzilla-Component=general
X-GNOME-Bugzilla-Version=3.28.0
X-AppStream-Ignore=true
X-Ubuntu-Gettext-Domain=GitAhead
一:一些资料:
官方电子书: 只需要认真看完前100页就可以熟练应用git常见命令了;非常详细;
服务器端的电子书:
https://git-scm.com/book/zh/v1/服务器上的-Git
作为目前较为重要的两个版本管理系统,都很好, 或许每个人有不同的观点;
简明的说一下:
svn: 是将本地文件 提交到服务器上, 所有的历史记录,信息,比较,都要联网到服务器;
git:可以在本地完成提交比较,可以简单理解为本地服务器管理, 完成后可以提交到公共服务器;
“git官方文档”:
https://git-scm.com/book/zh/v1/Git-%E5%9F%BA%E7%A1%80-%E5%8F%96%E5%BE%97%E9%A1%B9%E7%9B%AE%E7%9A%84-Git-%E4%BB%93%E5%BA%93
git status :查看文件状态;
git cherry -v :查看 commit ,是否 push ;
二:一些概念:
git没有客户端和服务端的概念;
安装完成git后,可以直接在本地计算机上应用,通常建立的gitlab,gitblit等服务端,是为了在广域网上更好的协同工作;
git的本地数据和服务上,基本是一样的;
git可以通过commit提交到本地数据库,不需要联网,这样就可以本地就可以查看历史记录;
git在commit之后,可以通过push,提交到远程仓库中;别人可以看到;
三:一些本地应用:
简单说明在Windows上的应用;
一:如果想要自己记录文件变化,那么,可以直接在指定的文件夹上创建远端仓库repository;
(1):通过tortoise创建:
(1.1)直接右键到指定文件夹-》Git Create repository here.. ->Make It Bare...
(1.1.1): 如果不勾选Make It Bare...: 那么这个文件就直接是文件仓库,可以修改,和commit;
(1.1.2):如果勾选Make It Bare...:那么表示这个文件夹更像类似于远端仓库;
创建后,需要在新的文件夹中clone这个仓库路径(本机就是绝对路径),然后添加删除修改文件等,
可以commit,push,还可以和其它客户端同步;
这样更有利于资料登等信息的记录,不需要搭建服务端相关的更多东西;
四:关于服务器端:
通常建立的gitlab,gitblit等服务端,是为了在广域网上更好的协同工作;
1:gitlab:功能比较强大和复杂,一般公司都用的这个作为git服务器端;
gitlab目前没有Windows平台软件,所以如果想在Windows上测试熟悉,可以用gitblit;
2:gitblit:我觉得,现在的gitblit-1.8.0版本已经非常简化好用了;
这里以Windows上的gitblit安装应用作为示例;
gitlab docker 安装更加简单方便;
直接参考官网: GitLab Docker images | GitLab
按照 docker,然后到这里命令行获取 gitlab 镜像;
如果密码 默认在
gitlab 不支持在 win 上直接安装,但是可以通过 Ubuntu 子系统安装;
167 sudo mkdir gitlab
168 ls
169 cd gitlab/
170 ls
171 sudo mkdir data
172 sudo mkdir logs
173 sudo mkdir config
174 ls
175 export GITLAB_HOME=/srv/gitlab
176 sudo docker run --detach --hostname 192.168.17.131 --publish 443:443 --publish 80:80 --publish 22:22 --name gitlab --restart always --volume $GITLAB_HOME/config:/etc/gitlab --volume $GITLAB_HOME/logs:/var/log/gitlab --volume $GITLAB_HOME/data:/var/opt/gitlab --shm-size 256m gitlab/gitlab-ee:latest
177 git clone http://192.168.17.131/gitlab-instance-df0928c2/testgitlabproject1.git
上述是官方文档:
如果自己测试用:
用社区办 gitlab docker image,ce 版本:
https://hub.docker.com/r/gitlab/gitlab-ce
命令行可以不做磁盘关联,直接启动,
sudo docker run --detach --hostname 192.168.17.131 --publish 443:443 --publish 80:80 --publish 22:22 --name gitlab --restart always --shm-size 256m gitlab/gitlab-ce:latest
然后,直接网页启动,ip,默认80端口,不用输入;
用户名:
root
密码查看:
sudo docker exec -it gitlab grep 'Password:' /etc/gitlab/initial_root_password
The password file will be automatically deleted in the first reconfigure run after 24 hours.
登录后,可以通过这里选择 edit ,设置密码:
http://192.168.0.97/admin/users/root
五:gitblit安装:
1:win10 + git + tortoiseGit; 为了方便测试;
2:安装jdk;我这里安装的是JDK1.8version,有更加新的jdk版本,这个应该算是目前比较常用的版本;
3:安装jdk版本建议,不要有空格等;
配置环境变量的时候,在win10上,要用绝对路径,不可以用JAVA_HOME代替;
4:下载gitblit;
下载Gitblit.下载地址:Gitblit
5:Windows行,Gitblit是一个压缩文件,直接解压到目录就可以了;一般解压的非系统盘,解压目录如下:
6:一些配置:
网上的一些资料说,要先配置一些参数,这个版本已经设置了默认参数,可以直接启动测试,如有需要在修改;
默认参数文件:gitblit-1.8.0\data\defaults.properties
但是可以先配置,http的ip和port;方便web访问;
server.httpBindInterface = 10.12.9.126 本机IP;
server.httpPort = 10101 指定端口;
这个文件里包含了具体网上所说的参数配置,具体自己查看修改;
“数据”目录是默认的目录,包含配置文件和相关参数,还有默认的远程仓库目录(data/git);
7:启动服务端:
直接双击启动:gitblit.cmd
8:web访问:可以直接http://10.12.9.126:10101
六:gitblit web应用;
通过页面,可以创建,团队,用户,权限,项目等;
1:打开页面后,右上角点击用户图标登录;默认用户名,密码是admin;
2:创建项目,远程仓库:
创建的目录就在data目录下;跟需要创建相对目录;
3:创建用户和团队:
创建的时候,可以设置相关权限;
4: clone 获取远程仓库;
5:页面项目中,有相关工具的相关git路径,可以自己查看;
关于gitblit服务的安装,我这里仅做测试,直接启动应用就可以了,如果想要添加启动服务,可以查找更多资料;
推荐两篇文章,可以参考:
https://www.cnblogs.com/jeremylee/p/5626240.html
《HEAD、master 与 branch》
from:HEAD、master 与 branch - 简书
这一节主要是几个概念的解释:HEAD、master 以及 Git 中非常重要的一个概念: branch。
引用:commit 的快捷方式
首先,再看一次 log
:
git log
第一行的 commit
后面括号里的 HEAD -> master, origin/master, origin/HEAD
,是几个指向这个 commit
的引用。在 Git 的使用中,经常会需要对指定的 commit
进行操作。每一个 commit
都有一个它唯一的指定方式——它的 SHA-1 校验和,也就是上图中每个黄色的 commit
右边的那一长串字符。两个 SHA-1 值的重复概率极低,所以你可以使用这个 SHA-1 值来指代 commit
,也可以只使用它的前几位来指代它(例如第一个 78bb0ab7d541…16b77
,你使用 78bb0ab
甚至 78bb
来指代它通常也可以),但毕竟这种没有任何含义的字符串是很难记忆的,所以 Git 提供了「引用」的机制:使用固定的字符串作为引用,指向某个 commit
,作为操作 commit
时的快捷方式。
HEAD:当前 commit 的引用
上一段里说到,图中括号里是指向这个 commit
的引用。其中这个括号里的 HEAD
是引用中最特殊的一个:它是指向当前 commit
的引用。所谓当前 commit
这个概念很简单,它指的就是当前工作目录所对应的 commit
。
例如上图中的当前 commit
就是第一行中的那个最新的 commit
。每次当有新的 commit
的时候,工作目录自动与最新的 commit
对应;而与此同时,HEAD
也会转而指向最新的 commit
。事实上,当使用 checkout
、reset
等指令手动指定改变当前 commit
的时候,HEAD
也会一起跟过去。
总之,当前 commit
在哪里,HEAD
就在哪里,这是一个永远自动指向当前 commit
的引用,所以你永远可以用 HEAD
来操作当前 commit
。
branch
HEAD
是 Git 中一个独特的引用,它是唯一的。而除了 HEAD
之外,Git 还有一种引用,叫做 branch
(分支)。HEAD
除了可以指向 commit
,还可以指向一个 branch
,当它指向某个 branch
的时候,会通过这个 branch
来间接地指向某个 commit
;另外,当 HEAD
在提交时自动向前移动的时候,它会像一个拖钩一样带着它所指向的 branch
一起移动。
例如上面的那张图里,HEAD -> master
中的 master
就是一个 branch
的名字,而它左边的箭头 ->
表示 HEAD
正指向它(当然,也会间接地指向它所指向的 commit
)。
如果我在这时创建一个 commit
,那么 HEAD
会带着 master
一起移动到最新的 commit
:
git commit
通过查看 log
,可以对这个逻辑进行验证:
git log
从图中可以看出,最新的 commit
(提交信息:"Add feature1")被创建后,HEAD
和 master
这两个引用都指向了它,而在上面第一张图中的后两个引用 origin/master
和 origin/HEAD
则依然停留在原先的位置。
master: 默认 branch
上面的这个 master
,其实是一个特殊的 branch
:它是 Git 的默认 branch
(俗称主 branch
/ 主分支)。
所谓的「默认 branch」,主要有两个特点:
- 新创建的 repository(仓库)是没有任何
commit
的。但在它创建第一个commit
时,会把master
指向它,并把HEAD
指向master
。
-
当有人使用
git clone
时,除了从远程仓库把.git
这个仓库目录下载到工作目录中,还会checkout
(签出)master
(checkout
的意思就是把某个commit
作为当前commit
,把HEAD
移动过去,并把工作目录的文件内容替换成这个commit
所对应的内容)。
另外,需要说一下的是,大多数的开发团队会规定开发以 master
为核心,所有的分支都在一定程度上围绕着 master
来开发。这个在事实上构成了 master
和其它分支在地位上的一个额外的区别。
branch 的通俗化理解
尽管在 Git 中,branch
只是一个指向 commit
的引用,但它有一个更通俗的理解:你还可以把一个 branch
理解为从初始 commit
到 branch
所指向的 commit
之间的所有 commit
s 的一个「串」。例如下面这张图:
master
的本质是一个指向 3
的引用,但你也可以把 master
理解为是 1
2
3
三个 commit
的「串」,它的起点是 1
,终点是 3
。
这种理解方式比较符合 branch
这个名字的本意(branch 的本意是树枝,可以延伸为事物的分支),也是大多数人对 branch
的理解。不过如果你选择这样理解 branch
,需要注意下面两点:
- 所有的
branch
之间都是平等的。
例如上面这张图,`branch1` 是 `1` `2` `5` `6` 的串,而不要理解为 `2` `5` `6` 或者 `5` `6` 。其实,起点在哪里并不是最重要的,重要的是你要知道,所有 `branch` 之间是平等的,`master` 除了上面我说的那几点之外,并不比其他 `branch` 高级。这个认知的理解对于 `branch` 的正确使用非常重要。
换个角度来说,上面这张图我可以用别的画法来表达,它们的意思是一样的:
通过这张动图应该能够对「平等」这个概念更好地理解了吧?
branch
包含了从初始commit
到它的所有路径,而不是一条路径。并且,这些路径之间也是彼此平等的。
像上图这样,`master` 在合并了 `branch1` 之后,从初始 `commit` 到 `master` 有了两条路径。这时,`master` 的串就包含了 `1` `2` `3` `4` `7` 和 `1` `2` `5` `6` `7` 这两条路径。而且,这两条路径是平等的,`1` `2` `3` `4` `7` 这条路径并不会因为它是「原生路径」而拥有任何的特别之处。
如果你喜欢用「树枝」的概念来理解 Git 的 branch
,一定要注意上面说的这两点,否则在今后使用 branch
的时候就可能与出现理解偏差或者使用方式不当的问题。事实上我本人并不喜欢用这种方式来理解 branch
,因为觉得它有点舍近求远的味道:我为了「直观」地思考,给它了一个形象的比喻,但由于它的本质含义其实更加简单,导致我的这种比喻反而增加了思考它时的复杂度,未免有点画蛇添足。不过这是我自己的感受,怎么理解 branch
是个个人偏好的问题,这两种理解方式你选一个喜欢的就好。
branch 的创建、切换和删除
创建 branch
如果你想在某处创建 branch
,只需要输入一行 git branch 名称
。例如你现在在 master
上:
你想在这个 commit
处创建一个叫做 "feature1" 的 branch
,只要输入:
git branch feature1
你的 branch
就创建好了:
切换 branch
不过新建的 branch
并不会自动切换,你的 HEAD
在这时依然是指向 master
的。你需要用 checkout
来主动切换到你的新 branch
去:
git checkout feature1
然后 HEAD
就会指向新建的 branch
了:
除此之外,你还可以用 git checkout -b 名称
来把上面两步操作合并执行。这行代码可以帮你用指定的名称创建 branch
后,再直接切换过去。还以 feature1
为例的话,就是:
git checkout -b feature1
在切换到新的 branch
后,再次 commit
时 HEAD
就会带着新的 branch
移动了:
git commit
而这个时候,如果你再切换到 master
去 commit
,就会真正地出现分叉了:
git checkout master
...
git commit
删除 branch
删除 branch
的方法非常简单:git branch -d 名称
。例如要删除 feature1
这个 branch:
git branch -d feature1
需要说明的有两点:
-
HEAD
指向的branch
不能删除。如果要删除HEAD
指向的branch
,需要先用checkout
把HEAD
指向其他地方。 -
由于 Git 中的
branch
只是一个引用,所以删除branch
的操作也只会删掉这个引用,并不会删除任何的commit
。(不过如果一个commit
不在任何一个branch
的「路径」上,或者换句话说,如果没有任何一个branch
可以回溯到这条commit
(也许可以称为野生commit
?),那么在一定时间后,它会被 Git 的回收机制删除掉。) -
出于安全考虑,没有被合并到
master
过的branch
在删除时会失败(因为怕你误删掉「未完成」的branch
啊):
这种情况如果你确认是要删除这个 `branch` (例如某个未完成的功能被团队确认永久毙掉了,不再做了),可以把 `-d` 改成 `-D`,小写换成大写,就能删除了。
「引用」的本质
所谓「引用」(reference),其实就是一个个的字符串。这个字符串可以是一个 commit
的 SHA-1 码(例:c08de9a4d8771144cd23986f9f76c4ed729e69b0
),也可以是一个 branch
(例:ref: refs/heads/feature3
)。
Git 中的 HEAD
和每一个 branch
以及其他的引用,都是以文本文件的形式存储在本地仓库 .git
目录中,而 Git 在工作的时候,就是通过这些文本文件的内容来判断这些所谓的「引用」是指向谁的。
小结
这一节介绍了 Git 中的一些「引用」:HEAD
、master
、branch
。这里总结一下:
HEAD
是指向当前commit
的引用,它具有唯一性,每个仓库中只有一个HEAD
。在每次提交时它都会自动向前移动到最新的commit
。branch
是一类引用。HEAD
除了直接指向commit
,也可以通过指向某个branch
来间接指向commit
。当HEAD
指向一个branch
时,commit
发生时,HEAD
会带着它所指向的branch
一起移动。master
是 Git 中的默认branch
,它和其它branch
的区别在于:- 新建的仓库中的第一个
commit
会被master
自动指向; - 在
git clone
时,会自动checkout
出master
。
- 新建的仓库中的第一个
branch
的创建、切换和删除:- 创建
branch
的方式是git branch 名称
或git checkout -b 名称
(创建后自动切换); - 切换的方式是
git checkout 名称
; - 删除的方式是
git branch -d 名称
。
- 创建