书接上回,笔者在丐版云服务器上安装了Git,准备将其作为中心仓库继续发光发热。当然版本控制的消费方则是笔者的丐版mbp。
服务器环境:
这里笔者给读者朋友提示一下实操之前的两点注意:(实则告诫自己这个小白)
通过上面两点我们能够了解到一个事情:两边服务器其实都需要进行git init来初始化仓库
接下来我们进行实操(按流程走即可):
一. 中心仓库服务器配置
#git_2.38.1是笔者的安装路径
useradd —d /data/git_2.38.1/ —m gitmanager #新建管理Git的账号
passwd gitmanager #修改账号密码
chown gitmanager.gitmanager data/git_2.38.1 #修改Git文件夹所有者
mkdir /data/git_2.38.1/Git_Repo #新建仓库文件夹
mkdir /data/git_2.38.1/Git_Repo/自定义仓库名.git
遵循Git仓库命名规则,仓库名+.git
git config --global user.name "git账户名"
git config --global user.email "git邮箱"
进入自定义仓库的文件夹(仓库名.git),按顺序执行下面的命令
git init #或者git --bare init
touch README #创建初始化文件
git add README #对README进行版本跟踪,从工作区中转移至暂存区
git commit -m '初次提交,进行仓库初始化' README #提交初始化文件到Git版本库中
#代码仓库初始化结束
#必须这样做提交才不会出现某些异常,异常原因请看问题总结
#如果在初始化结束之后不要相关的初始化文件就执行下面的命令
git rm -r README
git commit -m '删除初始化文件' README
从Git仓库获取代码有如下方式:
#直接从远程仓库拉到本地工作区,实际上是fetch+master
git pull <远程主机名> <远程分支名>:<本地分支名>
git clone 远程仓库地址
#或者
git fetch [alias]
#差别在于是否是新的本地仓库
#再切换至需要的分支
git checkout branchname
重点不在这,在于每次使用上面的命令都需要账号/密码。这属实有点烦人,但我们可以通过Linux服务器的ssh密钥登陆模式避免输入Git账号。以笔者环境为例:
1) 检查gitmanager用户(服务端Git账号)的家目录是否有.ssh文件,没有则创建
2) 检查.ssh文件下面是否有authorized_keys,没有则新建
3) 最后一步则是设置相关文件权限之后,将客户端生成的id_rsa.pub文件中内容复制到服务端authorized_keys中
可使用如下命令完成:
chmod 700 /data/git_2.38.1/.ssh
chmod 600 /data/git_2.38.1/.ssh/authorized_keys
cat git账号家目录/.ssh/id_rsa.pub>>git账号家目录/.ssh/authorized_keys
二. 代码版本控制服务器配置
与本文服务端操作相同
与本文服务端操作相同
1) 检查本地仓库用户的家目录是否有.ssh文件,没有则创建
2) 使用指令进行RSA密钥的创建:
ssh-keygen -t rsa -C "[email protected]" -o
ssh-keygen的指令:
-t dsa | ecdsa | ed25519 | rsa | rsa1
指定要创建的密钥的类型。可能的值为协议版本1的“rsa1”和“dsa”,“ecdsa”,“ed25519”或协议版本2的“rsa”
-o Causes ssh-keygen to save private keys using the new OpenSSH format rather than the more compatible PEM format. The new format has increased resistance to brute-force password cracking but is not supported by versions of OpenSSH prior to 6.5. Ed25519 keys always use the new private key format。言下之意就是加-o选项就可以比不加选项的密钥拥有更强的安全性
3) 等待指令运行结束即可在.ssh文件下找到id_rsa.pub、id_rsa密钥文件
在项目中其实有很多文件不需要提交,如:node_modules、.idea、.iml等。如果需要避免 这些文件在提交时带来的苦恼,那么就需要配置一个.gitignore文件。具体操作如下:
#在仓库下建立文件.gitignore文件
#编写方式
#开头的为注释内容
*匹配0个或者多个字符
!用来匹配否定结果
/放在开头就是根目录,放在中间或者后面就是当前目录下
**匹配多级目录
Git:
#导出最新的当前分支版本库
git archive -o ../latest.zip HEAD
#将当前master分支导出为tgz压缩模式
git archive master | gzip > project.tgz
#将特定版本导出为tar.gz压缩模式
git archive 9976c24 | gzip > ../version-1.0.0.tar.gz
Svn:
svn export [-r 版本号] svn路径 [本地目录全路径] --username
到这里基本算是构建结束了,当然前两步也有一些:.gitignore文件配置、从git、svn导出无版本控制项目这样一些用不上的步骤。接下来就是笔者在构建过程中踩过的坑及爬出来的方法:
三.流程中问题总结
由于笔者在安装代码仓库服务器的Git时选择了自定义的文件夹,这样就会导致/usr/bin这个默认地址中没有git操作指令。远端进行操作时会出现报错:git-upload-pack: command not found或者git-receive-pack: command not found。为了解决这个问题,制作软链接如下:
ln -s git安装地址下的bin命令 /usr/bin/git命令
#或者在使用git命令的时候指定bin地址即可
git clone --upload-pack "git bin真实地址" git仓库地址
这一点其实只是想提醒一下刚接触Git的小伙伴,在使用Git clone命令下载仓库的时候其实会在本地生成仓库名文件夹,自己在客户端定义反而会破坏文件目录结构。如:代码控制服务器有个仓库的名字为test.git,然后使用者需要将其clone到远端/git/下面。直接使用clone命令将test仓库克隆下来之后会发现,git文件夹下面创建了test文件。这一点和svn有点区别,需要确定下载的文件夹目录结构。
这个问题的出现原因其实在笔者这边是混淆git init和git -- bare init两个建库命令。作为中心仓库来说用git -- bare init很正确,因为其只作为版本控制工具。一般都是远程操作,要避免在中心仓库服务器上进行操作。所以也就没有对工作区(work tree)的需求。一旦你用git -- bare init创建仓库之后,在中心仓库所在文件夹下面进行git命令操作,肯定告诉你:this operation must be run in a work tree,因为没有work tree嘛。
如果你因为前期创建仓库失误导致这样的报错可以通过下面的命令来进行处理或者直接重建git仓库,因为这种问题一般出现在建库早期或者选错git路径也有可能。针对这两点有两个解决方式:
1.在此仓库下新建文件夹,进入之后执行
git --bare init #可能一开始已经执行过这个指令了
touch README
git init
git add README
git commit -m 'init reporsitory' README
2.这一块是参照stackoverflow大手子的方法,但好像不会在裸仓库生效,具体的各位可以试试
执行命令来解决:git config --bool core.bare true
这里拓展一下git init和git --bare init的区别:
git仓库在初始化时有两种不一样的初始化方式:git init和git --bare init
前者执行完毕之后生成的仓库为标准Git仓库,后者执行完毕后生成的仓库为裸仓库也就代表没有工作区。因为前者有工作区,所以在将git init创建的仓库作为中心仓库的时候,远程提交会出现提示:remote: error: 默认禁止更新非纯仓库的当前分支,因为您推送的内容将导致索引和工作区不一致。
原因在于如果远程仓库正在远端push的分支上, 那么push后的结果不会反应在工作区上, 即在远程仓库的目录下对应的文件还是之前的内容,必须得使用git reset –hard 回退到此时版本库被提交后HAED所在位置。这样才能工作区看到远程push后的内容,如果当时不在远程仓库不在远端push的分支上,就没有问题。由于裸仓库不包含工作区,所以不能在裸仓库服务器上直接提交变更。
具体两者生成仓库的目录结构:
标准仓库中包含.git文件夹,当前文件夹为工作区
裸仓库中不包含.git文件夹,而是将.git文件夹内容放到了当前文件夹,这样就没有工作区一说
所以裸仓库适用于远程仓库,裸仓库可以直接作为服务器仓库供各开发者push、pull数据,实现数据共享和同步,保存历史提交的版本信息。裸库往往被创建用于作为共享库,工作人员往里面push自己的本地修改。裸仓库惯用的命名方式是在库名后加上.git。这也是为什么从GitHub clone仓库的时候,地址都是 xxx.git 这样的形式的原因。
这里可以注意一下,裸仓库虽然没有工作区,但是远端push的内容一样会被保存。没有的只是工作区的源文件。 源文件以压缩包的形式存在仓库文件夹里。
(1)、在使用命令ssh-keygen -t rsa -C "[email protected]" -o创建ssh密钥的过程中,会提示你选择需要将ssh密钥生成到自定义位置及位置。笔者当时就自定了文件名,却不知道这样操作会导致代码版本控制服务器识别不了自定义的pub文件内容。所以这里最好生成ssh密钥的时候在提示:Enter file in which to save the key(/Users/username/.ssh/id) 时直接回车跳过,否则需要配置ssh密钥多版本控制
(2)、为了防止代码版本控制服务器每次操作需要输入密码,在生成ssh密钥过程中出现Enter new passphrase/Enter same passphrase again时直接回车跳过。这样就不会设置密码,每次操作就不用输入passphrase
(1)、远程仓库别名可能会失效,具体体现在于在使用git命令远程仓库别名时报错:fatal: 'origin' does not appear to be a git repository fatal: Could not read from remote repository. 在这种情况下重新建立远程连接即可:
git remote add + git地址
(2)、在不同的git仓库文件夹下面远程仓库的别名会失效需要重新建立
四. 构建过程中使用到的GIT命令
#配置Git账户信息
git config --global user.name "git账户名"
git config --global user.email "git邮箱"
#仓库初始化
git init
git --bare init
#设置远程仓库
git remote add + git地址
#拉取远程仓库内容
git pull <远程主机名> <远程分支名>:<本地分支名>
git clone 远程仓库地址
git fetch [alias]
#本地切换分支
git checkout branchname
#提交本地修改
git add filename
git commit -m 'commit message' filename
git push repository_name branch_name
#删除修改
git rm filename
git commit -m "commit message" filename
git push repository_name branch_name
#回退版本库
git reset --soft
git reset --mixed
git reset --hard
#清除未被Git追踪的文件
git clean -nfd #-f: --force,强制删除untracked文件 -d:删除整个文件夹,-fd强制删除untracked文件和文件夹 -n: 查看会删掉哪些文件,防止重要文件被误删
五. Git可视化工具使用
笔者使用的是GitHub DeskTop软件,下载地址为:
GitHub DeskTophttps://desktop.github.com第一次打开软件有两种情况:
1. 创建本地仓库
File->New Repository
2.增加本地仓库
File->Add Local Repository
3.克隆仓库
File->Clone Repository
通过上面的方式建立仓库或者链接运程仓库之后就是正常的Git操作了,详细请看之后的Git常用操作文档