正确的版本控制系统的使用方法是: 一次提交只干一件事, 或者完成一个新的功能, 或者是修改了一个Bug
将目录/usr/share/doc/git/contrib/git-shell-commands拷贝到git用户下/home/git/
修改所有者chown -R git.git git-shell-commands
如果该目录下的help和list没有执行权,那么再给它加执行权
chmod +x /home/git/git-shell-commands/help
chmod +x /home/git/git-shell-commands/list
先选定一个目录作为Git仓库,假定是/srv/sample.git,在/srv目录下输入命令: $ sudo git init --bare sample.git Git就会创建一个裸仓库,裸仓库没有工作区,因为服务器上的Git仓库纯粹是为了共享,所以 不让用户直接登录到服务器上去改工作区,并且服务器上的Git仓库通常都以.git结尾。 然后,把owner改为git: $ sudo chown -R git:git sample.git git裸仓库,就是指没有工作目录的仓库。简单点说,裸仓库就是工作目录下面的 .git 子目录里面的内容。远程仓库,一般不需要工作目录,所以通常都是裸仓库。
如何将本地已有代码部署到服务器上,并且仅仅部署成一个裸仓库呢?
方式1
$ mkdir cdr $ cd cdr $ git init . $ git add ./ $ git commit -m "add uvc camera, and support change preview" $ git clone --bare cdr/ cdr.git 将生成的cdr.git拷贝到服务器 sudo scp -r cdr.git /Repo/ sudo chown -R git:git cdr.git 检出副本: git clone git@localhost:/Repo/cdr.git/
方式2
把本机的.git目录部署到服务器上,然后改成裸仓库 例如: scp -r .git git@server:/Repo/cdr.git
git的三个配置文件分别是:
例:
git config --global user.name "caodan" git config --global user.email "caodan@linuxtoy.cn" git config --global color.ui true git config --global core.editor vim git config --global gui.encoding utf8
git add [path] 添加指定的文件到暂存区 git add -u [path] 将path中所有tracked文件中被修改过或者已删除文件的信息添加到暂存区, 但不会处理untracked的文件 git add -A [path] 把path中所有tracked文件中被修改过或已删除文件和所有untracted的文件 信息添加到暂存区
git diff
修改后的文件通过git add命令提交到暂存区后,再执行git diff 命令后,将看不到该文件的差异
继续对该文件进行修改,再次执行git diff 命令,会看到新的修改显示在差异中,而看不到旧的修改
git diff HEAD
HEAD是当前活跃分支的游标,可以认为HEAD(大写)是“current branch”(当下的分支)
使用git checkout切换分支的时候,HEAD 指向新的分支。有的时候HEAD会指向一个没有分支名字的修订版本,这种情况叫”detached HEAD“
git diff --cached
git diff --name-only [HEAD|--cached]
中括号中的参数同1、2、3点中所述
5. 文件不同版本间的比较
git diff <commit1> <commit2> -- <paths>
6. 比较一个文件在两个tag之间的不同
git diff tag1:file tag2:file
$ git log
commit 20c210c9949875df94172d3269433bcd6200d7c7
Author: xxx <xxx@xxx.cn>
Date: Sun Dec 13 22:13:20 2015 +0800
free software
commit 03f430b9474231fcb7fdb5527cec27f9146ab584
Author: xxx <xxx@xxx.cn>
Date: Sun Dec 13 22:12:00 2015 +0800
add descriptions
commit bfed7fb5d163c02ca66fac05d8f1b14961ba7f1a
Author: xxx <xxx@linuxtoy.cn>
Date: Sun Dec 13 22:11:15 2015 +0800
init test prj
回到到上一个版本:
$ git reset --hard HEAD^
HEAD is now at 03f430b add descriptions
$ git log
commit 03f430b9474231fcb7fdb5527cec27f9146ab584
Author: xxx <xxx@linuxtoy.cn>
Date: Sun Dec 13 22:12:00 2015 +0800
add descriptions
commit bfed7fb5d163c02ca66fac05d8f1b14961ba7f1a
Author: xxx <xxx@linuxtoy.cn>
Date: Sun Dec 13 22:11:15 2015 +0800
init test prj
回退之后,log里面只能看到两次提交记录,如果要撤销回退,怎么才能回到刚才的版本?
如果还记得版本的commit id, 例如20c210c, 那么可以使用如下方式指定回退到未来的某个版本。
版本号没必要写全,前几位就可以了,Git会自动去找。当然也不能只写前一两位,因为Git可能会找到多个版本号,就无法确定是哪一个了。
$ git reset --hard 20c210c
HEAD is now at 20c210c free software
如果不记得未来版本的commit id, 那怎么办?
git 提供了一个命令 git reflog来记录你每次的操作, 可以查找到commit id
$ git reflog
03f430b HEAD@{2}: reset: moving to HEAD^
20c210c HEAD@{3}: commit: free software
03f430b HEAD@{4}: commit: add descriptions
bfed7fb HEAD@{5}: commit (initial): init test prj
# 远程仓库与分支
## 查看远程仓库信息
git remote 列出已经存在的远程仓库
git remote -v 列出远程仓库的详细信息,每个名字后面列出其远程url
git remote show <remote-name> 查看单个远程仓库的信息
$ git remote -v
origin git@linuxtoy.cn:/data/repo/mywiki.git (fetch)
origin git@linuxtoy.cn:/data/repo/mywiki.git (push)
$ git remote show vimrc
* 远程 vimrc
获取地址:https://github.com/caodan4linux/vimrc
推送地址:https://github.com/caodan4linux/vimrc
HEAD分支:master
远程分支:
master 已跟踪
为 'git push' 配置的本地引用:
master 推送至 master (最新)
## 添加或删除远程仓库
git remote add <name> <url> 添加一个位于url的命名为name的远程仓库
git remote remove <name>
git remote rename <oldname> <newname>
git remote add origin https://github.com/try-git/try_git.git
git push 远程仓库名 (本地分支名为空):远程分支名
例:
git push :DX_A20_CDR_V1.1 将删除远程分支DX_A20_CDR_V1.1
git branch -a
例如:
$ git branch -a * DX_A20_CDR_V1.1 a20-cdr-stable remotes/origin/DX_A20_CDR_V1.1 remotes/origin/HEAD -> origin/a20-cdr-stable remotes/origin/a20-cdr-stable
例如已经有一个仓库位于: 192.168.3.175:/home/extend/A20linuxrepo/A20CDRV1.1/camdroid.git/
现在需要建立一个镜像仓库与上面的仓库同步,
git clone --mirror caodan_1@192.168.3.175:/home/extend/A20_linux_repo/A20_CDR_V1.1/camdroid.git/ 就会在当前目录建立一个镜像仓库camdroid.git
更新镜像仓库:
进入camdroid.git目录, 执行 git remote update
使用.gitignore文件可以设置忽略的文件 如果在已经提交之后再设置.gitignore 需要使用 git rm –cached 命令删除缓存
例:
*.ko out .patch .ycm_extra_conf.py .ycm_extra_conf.pyc *.IAB *.IAD *.IMB *.IMD *.PFI *.PO *.PR *.PRI *.PS *.SearchResults *.WK3 cscope.* tags # # git files that we don't want to ignore # !app/newcdr/tools/MultiLingual/out
在前面加上感叹号!
表示不希望忽略的文件
http://kb.cnblogs.com/page/132209/
Git 可以使用四种主要的协议来传输数据:本地传输,SSH 协议,Git 协议和 HTTP 协议. 除了 HTTP 协议外,其他所有协议都要求在服务器端安装并运行 Git。
最基本的就是本地协议(Local protocol),所谓的远程仓库在该协议中的表示,就是硬盘上的另一个目录。 这常见于团队每一个成员都对一个共享的文件系统(例如 NFS)拥有访问权 如果你使用一个共享的文件系统,就可以在一个本地文件系统中克隆仓库,推送和获取。克隆的时候只需要将远程仓库的路径作为 URL 使用,比如下面这样: `git clone /opt/git/project.git` 或者 `git clone file:///opt/git/project.git` 如果在 URL 开头明确使用 file:// ,那么 Git 会以一种略微不同的方式运行。 如果你只给出路径,Git 会尝试使用硬链接或直接复制它所需要的文件。 如果使用了 file:// ,Git 会调用它平时通过网络来传输数据的工序,而这种方式的效率相对较低。 要添加一个本地仓库作为现有 Git 项目的远程仓库,可以这样做: `git remote add local_proj /opt/git/project.git`
Git 使用的传输协议中最常见的可能就是 SSH 了。 这是因为大多数环境已经支持通过 SSH 对服务器的访问 — 即便还没有,架设起来也很容易. SSH 也是唯一一个同时支持读写操作的网络协议。 另外两个网络协议(HTTP 和 Git)通常都是只读的,所以虽然二者对大多数人都可用,但执行写操作时还是需要 SSH。 SSH 同时也是一个验证授权的网络协议;而因为其普遍性,一般架设和使用都很容易。 通过 SSH 克隆一个 Git 仓库,你可以像下面这样给出 ssh:// 的 URL: `git clone ssh://user@server/project.git` 或者不指明某个协议 — 这时 Git 会默认使用 SSH : `git clone user@server:project.git`
优点:
首先,如果你想拥有对网络仓库的写权限,基本上不可能不使用 SSH。 其次,SSH 架设相对比较简单 — SSH 守护进程很常见,很多网络管理员都有一些使用经验,而且很多操作系统都自带了它或者相关的管理工具。 再次,通过 SSH 进行访问是安全的 — 所有数据传输都是加密和授权的。最后,和 Git 及本地协议一样,SSH 也很高效,会在传输之前尽可能压缩数据。
缺点:
SSH 的限制在于你不能通过它实现仓库的匿名访问。 即使仅为读取数据,人们也必须在能通过 SSH 访问主机的前提下才能访问仓库,这使得 SSH 不利于开源的项目。 如果你仅仅在公司网络里使用,SSH 可能是你唯一需要使用的协议。 如果想允许对项目的匿名只读访问,那么除了为自己推送而架设 SSH 协议之外,还需要支持其他协议以便他人访问读取。
ssh授权:
收集所有需要登录的用户的公钥,就是他们自己的id_rsa.pub文件, 把所有公钥导入到/home/git/.ssh/authorized_keys文件里,一行一个。
使用rsa认证:
-t rsa 表示生成的密钥的类型是rsa -C “192.168.3.132” 表示coment
caodan@caodan-ubuntu:/opt/Repository$ ssh-keygen -t rsa -C "192.168.3.132" Generating public/private rsa key pair. Enter file in which to save the key (/home/caodan/.ssh/id_rsa): /opt/Repository/rsa/id_rsa Enter passphrase (empty for no passphrase): Enter same passphrase again: Your identification has been saved in /opt/Repository/rsa/id_rsa. Your public key has been saved in /opt/Repository/rsa/id_rsa.pub. The key fingerprint is: 0a:eb:87:e7:90:9b:d7:87:d8:57:a3:a8:54:bd:cf:ee 192.168.3.132 The key's randomart image is: +--[ RSA 2048]----+ | | | | | | | . | | . S . | | + o .o | | +.o+ o.o . | | ..== = +o | | +=o. o oE | +-----------------+
管理公钥:
如果团队很小,把每个人的公钥收集起来放到服务器的/home/git/.ssh/authorized_keys文件里就是可行的。如果团队有几百号人,就没法这么玩了,这时,可以用Gitosis来管理公钥。
这是一个包含在 Git 软件包中的特殊守护进程; 它会监听一个提供类似于 SSH 服务的特定端口(9418),而无需任何授权。 打算支持 Git 协议的仓库,需要先创建 git-daemon-export-ok 文件 — 它是协议进程提供仓库服务的必要条件 — 但除此之外该服务没有什么安全措施。要么所有人都能克隆 Git 仓库,要么谁也不能。这也意味着该协议通常不能用来进行推送。 你可以允许推送操作;然而由于没有授权机制,一旦允许该操作,网络上任何一个知道项目 URL 的人将都有推送权限。 Git 协议是现存最快的传输协议。如果你在提供一个有很大访问量的公共项目,或者一个不需要对读操作进行授权的庞大项目,架设一个 Git 守护进程来供应仓库是个不错的选择。它使用与 SSH 协议相同的数据传输机制,但省去了加密和授权的开销。
Git 协议消极的一面是缺少授权机制。用 Git 协议作为访问项目的唯一方法通常是不可取的。 一般的做法是,同时提供 SSH 接口,让几个开发者拥有推送(写)权限,其他人通过 git:// 拥有只读权限。 Git 协议可能也是最难架设的协议。它要求有单独的守护进程,需要定制 该协议还要求防火墙开放 9418 端口,而企业级防火墙一般不允许对这个非标准端口的访问。 大型企业级防火墙通常会封锁这个少见的端口。
= HTTP/HTTPS协议 =
最后还有 HTTP 协议。HTTP 或 HTTPS 协议的优美之处在于架设的简便性。 基本上,只需要把 Git 的裸仓库文件放在 HTTP 的根目录下,配置一个特定的 post-update 挂钩(hook)就可以搞定