CentOS服务器上安装git(运维向)

(1).参考文献

官网在线教程:https://git-scm.com/book/zh/v2

官方网站:https://git-scm.com/

git源码包下载地址:https://www.kernel.org/pub/software/scm/git/

(2).实验环境

2核2G CentOS7.9.2009

注意:2.50.x及以上需要升级系统内核,2.46.x及以上版本需要升级 libcurl 7.30.0以上版本,剩余版本需要手动设置docbook2X的软连接。

(3).安装git

  1)yum或dnf安装

[root@localhost ~]# dnf -y install git-all

  2)源码安装

  想快速安装的请安装2.45.x及一下版本。我这里安装的是2.49.1版本,不升级内核,其他的报错尽量展示。

  注意:默认配置了阿里云yum源和yum -y install epel-release。

  安装依赖包,注意:如果git装在/usr目录下无需执行yum -y remove git。

[root@localhost ~]# yum -y install dnf
[root@localhost ~]# dnf -y install dh-autoreconf curl-devel expat-devel gettext-devel openssl-devel perl-devel zlib-devel    #这一步会装一个git-1.8.3.1-25.el7_9.x86_64
[root@localhost ~]# yum -y remove git  #去除自动安装的git
#为了添加文档的多种格式(doc、html、info),需要以下附加依赖
[root@localhost ~]# dnf -y install asciidoc xmlto docbook2X

  编译安装

[root@localhost ~]# tar xvf git-2.49.1.tar.xz
[root@localhost ~]# cd git-2.49.1
[root@localhost git-2.49.1]# make configure
GIT_VERSION = 2.49.1
    GEN configure
#如直接使用/usr那么git安装后的文件将会合并到/usr/bin、/usr/libexec、/usr/share目录下,好处是无需改动环境变量PATH,坏处是不好单独删,但可覆盖
[root@localhost git-2.49.1]# ./configure --prefix=/usr  
[root@localhost git-2.49.1]# echo $?    #检查上一个命令是否有异常
0
[root@localhost git-2.49.1]# make all doc info
In file included  from /usr/include/curl/curl.h:2251:0,
                 from git-curl-compat.h:3,
                 from http.c:5:
http.c: In function ‘set_proxyauth_name_password’:
http.c:645:28: error: ‘CURLOPT_PROXYHEADER’ undeclared (first use  in this function)
   curl_easy_setopt(result, CURLOPT_PROXYHEADER,
                            ^
http.c:645:28: note: each undeclared identifier  is reported only once  for each function it appears  in
http.c: In function ‘get_curl_http_version_opt’:
http.c:988:15: error: ‘CURL_HTTP_VERSION_2’ undeclared (first use  in this function)
   {  "HTTP/2" , CURL_HTTP_VERSION_2 }
               ^
In file included  from /usr/include/curl/curl.h:2251:0,
                 from git-curl-compat.h:3,
                 from http.c:5:
http.c: In function ‘get_curl_handle’:
http.c:1048:49: error: ‘CURLSSLOPT_NO_REVOKE’ undeclared (first use  in this function)
   curl_easy_setopt(result, CURLOPT_SSL_OPTIONS, CURLSSLOPT_NO_REVOKE);
                                                 ^
http.c:1089:28: error: ‘CURLOPT_PINNEDPUBLICKEY’ undeclared (first use  in this function)
   curl_easy_setopt(result, CURLOPT_PINNEDPUBLICKEY, ssl_pinnedkey);
                            ^
http.c:1089:3: error: invalid initializer
   curl_easy_setopt(result, CURLOPT_PINNEDPUBLICKEY, ssl_pinnedkey);
   ^
In file included  from /usr/include/curl/curl.h:2251:0,
                 from git-curl-compat.h:3,
                 from http.c:5:
http.c:1089:3: error: incompatible type  for argument 2 of ‘curl_easy_setopt’
   curl_easy_setopt(result, CURLOPT_PINNEDPUBLICKEY, ssl_pinnedkey);
   ^
In file included  from /usr/include/curl/curl.h:2244:0,
                 from git-curl-compat.h:3,
                 from http.c:5:
/usr/include/curl/easy.h:29:22: note: expected ‘CURLoption’ but argument  is of type ‘ struct  *’
 CURL_EXTERN CURLcode curl_easy_setopt(CURL *curl, CURLoption option, ...);
                      ^
In file included  from /usr/include/curl/curl.h:2251:0,
                 from git-curl-compat.h:3,
                 from http.c:5:
http.c:1093:28: error: ‘CURLOPT_PROXY_CAINFO’ undeclared (first use  in this function)
   curl_easy_setopt(result, CURLOPT_PROXY_CAINFO, NULL);
                            ^
http.c:1093:3: error: invalid initializer
   curl_easy_setopt(result, CURLOPT_PROXY_CAINFO, NULL);
   ^
In file included  from /usr/include/curl/curl.h:2251:0,
                 from git-curl-compat.h:3,
                 from http.c:5:
http.c:1093:3: error: incompatible type  for argument 2 of ‘curl_easy_setopt’
   curl_easy_setopt(result, CURLOPT_PROXY_CAINFO, NULL);
   ^
In file included  from /usr/include/curl/curl.h:2244:0,
                 from git-curl-compat.h:3,
                 from http.c:5:
/usr/include/curl/easy.h:29:22: note: expected ‘CURLoption’ but argument  is of type ‘ struct  *’
 CURL_EXTERN CURLcode curl_easy_setopt(CURL *curl, CURLoption option, ...);
                      ^
http.c:1098:4: error: invalid initializer
    curl_easy_setopt(result, CURLOPT_PROXY_CAINFO, http_proxy_ssl_ca_info);
    ^
In file included  from /usr/include/curl/curl.h:2251:0,
                 from git-curl-compat.h:3,
                 from http.c:5:
http.c:1098:4: error: incompatible type  for argument 2 of ‘curl_easy_setopt’
    curl_easy_setopt(result, CURLOPT_PROXY_CAINFO, http_proxy_ssl_ca_info);
    ^
In file included  from /usr/include/curl/curl.h:2244:0,
                 from git-curl-compat.h:3,
                 from http.c:5:
/usr/include/curl/easy.h:29:22: note: expected ‘CURLoption’ but argument  is of type ‘ struct  *’
 CURL_EXTERN CURLcode curl_easy_setopt(CURL *curl, CURLoption option, ...);
                      ^
In file included  from /usr/include/curl/curl.h:2251:0,
                 from git-curl-compat.h:3,
                 from http.c:5:
http.c:1195:48: error: ‘CURLPROXY_HTTPS’ undeclared (first use  in this function)
    curl_easy_setopt(result, CURLOPT_PROXYTYPE, CURLPROXY_HTTPS);
                                                ^
http.c:1198:30: error: ‘CURLOPT_PROXY_SSLCERT’ undeclared (first use  in this function)
     curl_easy_setopt(result, CURLOPT_PROXY_SSLCERT, http_proxy_ssl_cert);
                              ^
http.c:1198:5: error: invalid initializer
     curl_easy_setopt(result, CURLOPT_PROXY_SSLCERT, http_proxy_ssl_cert);
     ^
In file included  from /usr/include/curl/curl.h:2251:0,
                 from git-curl-compat.h:3,
                 from http.c:5:
http.c:1198:5: error: incompatible type  for argument 2 of ‘curl_easy_setopt’
     curl_easy_setopt(result, CURLOPT_PROXY_SSLCERT, http_proxy_ssl_cert);
     ^
In file included  from /usr/include/curl/curl.h:2244:0,
                 from git-curl-compat.h:3,
                 from http.c:5:
/usr/include/curl/easy.h:29:22: note: expected ‘CURLoption’ but argument  is of type ‘ struct  *’
 CURL_EXTERN CURLcode curl_easy_setopt(CURL *curl, CURLoption option, ...);
                      ^
In file included  from /usr/include/curl/curl.h:2251:0,
                 from git-curl-compat.h:3,
                 from http.c:5:
http.c:1201:30: error: ‘CURLOPT_PROXY_SSLKEY’ undeclared (first use  in this function)
     curl_easy_setopt(result, CURLOPT_PROXY_SSLKEY, http_proxy_ssl_key);
                              ^
http.c:1201:5: error: invalid initializer
     curl_easy_setopt(result, CURLOPT_PROXY_SSLKEY, http_proxy_ssl_key);
     ^
In file included  from /usr/include/curl/curl.h:2251:0,
                 from git-curl-compat.h:3,
                 from http.c:5:
http.c:1201:5: error: incompatible type  for argument 2 of ‘curl_easy_setopt’
     curl_easy_setopt(result, CURLOPT_PROXY_SSLKEY, http_proxy_ssl_key);
     ^
In file included  from /usr/include/curl/curl.h:2244:0,
                 from git-curl-compat.h:3,
                 from http.c:5:
/usr/include/curl/easy.h:29:22: note: expected ‘CURLoption’ but argument  is of type ‘ struct  *’
 CURL_EXTERN CURLcode curl_easy_setopt(CURL *curl, CURLoption option, ...);
                      ^
In file included  from /usr/include/curl/curl.h:2251:0,
                 from git-curl-compat.h:3,
                 from http.c:5:
http.c:1204:30: error: ‘CURLOPT_PROXY_KEYPASSWD’ undeclared (first use  in this function)
     curl_easy_setopt(result, CURLOPT_PROXY_KEYPASSWD, proxy_cert_auth.password);
                              ^
http.c:1204:5: error: invalid initializer
     curl_easy_setopt(result, CURLOPT_PROXY_KEYPASSWD, proxy_cert_auth.password);
     ^
In file included  from /usr/include/curl/curl.h:2251:0,
                 from git-curl-compat.h:3,
                 from http.c:5:
http.c:1204:5: error: incompatible type  for argument 2 of ‘curl_easy_setopt’
     curl_easy_setopt(result, CURLOPT_PROXY_KEYPASSWD, proxy_cert_auth.password);
     ^
In file included  from /usr/include/curl/curl.h:2244:0,
                 from git-curl-compat.h:3,
                 from http.c:5:
/usr/include/curl/easy.h:29:22: note: expected ‘CURLoption’ but argument  is of type ‘ struct  *’
 CURL_EXTERN CURLcode curl_easy_setopt(CURL *curl, CURLoption option, ...);
                      ^
http.c: In function ‘http_init’:
http.c:1280:3: error: unknown type name ‘curl_ssl_backend’
   const curl_ssl_backend **backends;
   ^
http.c:1284:3: warning:  implicit declaration of function ‘curl_global_sslset’ [-Wimplicit-function-declaration]
   switch (curl_global_sslset(-1, http_ssl_backend, &backends)) {
   ^
http.c:1285:8: error: ‘CURLSSLSET_UNKNOWN_BACKEND’ undeclared (first use  in this function)
   case CURLSSLSET_UNKNOWN_BACKEND:
        ^
http.c:1290:44: error: request  for member ‘name’  in something not a structure or union
     strbuf_addf(&buf,  "\n\t%s" , backends[i]->name);
                                            ^
http.c:1292:8: error: ‘CURLSSLSET_NO_BACKENDS’ undeclared (first use  in this function)
   case CURLSSLSET_NO_BACKENDS:
        ^
http.c:1296:8: error: ‘CURLSSLSET_TOO_LATE’ undeclared (first use  in this function)
   case CURLSSLSET_TOO_LATE:
        ^
http.c:1299:8: error: ‘CURLSSLSET_OK’ undeclared (first use  in this function)
   case CURLSSLSET_OK:
        ^
http.c: In function ‘handle_curl_result’:
http.c:1799:37: error: ‘CURLE_SSL_PINNEDPUBKEYNOTMATCH’ undeclared (first use  in this function)
  }  else if (results->curl_result == CURLE_SSL_PINNEDPUBKEYNOTMATCH) {
                                     ^
http.c:1799:34: warning: comparison between pointer and integer [enabled  by default ]
  }  else if (results->curl_result == CURLE_SSL_PINNEDPUBKEYNOTMATCH) {
                                  ^
make: *** [http.o] Error 1

  

  这里有一长串的报错,都是由于libcurl版本过低导致的。CentOS7官方支持的版本只到curl 7.29.0 ,所以需要进行源码编译安装,包下载地址:https://curl.se/download/

  另外高版本的curl需要依赖高版本的OpenSSL,请参照CentOS7升级OpenSSL3.5.4 - 苦逼运维 - 博客园对OpenSSL进行升级。注意:yum -y groupinstall "Development Tools"这一步会安装上git,需要多运行一步yum -y remove git

[root@localhost ~]# yum -y remove git
[root@localhost ~]# yum -y install libpsl libpsl-devel  #安装依赖
[root@localhost ~]# tar xvf curl-8.18.0.tar.xz
[root@localhost ~]# cd curl-8.18.0
[root@localhost curl-8.18.0]# ./configure --with-openssl=/usr/local/openssl-3.5.4 --prefix=/usr/local/curl-8.18.0
[root@localhost curl-8.18.0]# echo $?    #检查上一个命令是否有异常
0
[root@localhost curl-8.18.0]# make -j$(nproc)    #最大内核数进行编译
[root@localhost curl-8.18.0]# echo $?    #检查上一个命令是否有异常
0
[root@localhost curl-8.18.0]# make install
[root@localhost curl-8.18.0]# echo $?    #检查上一个命令是否有异常
0
[root@localhost curl-8.18.0]# echo  "export PATH=/usr/local/curl-8.18.0/bin:$PATH" >>/etc/profile
[root@localhost curl-8.18.0]# source /etc/profile
[root@localhost curl-8.18.0]# curl --version    #验证
curl 8.18.0 (x86_64-pc-linux-gnu) libcurl/8.18.0 OpenSSL/3.5.4 zlib/1.2.7 libpsl/0.7.0 (+libicu/50.1.2)
Release-Date: 2026-01-07
Protocols: dict file ftp ftps gopher gophers http https imap imaps ipfs ipns mqtt pop3 pop3s rtsp smb smbs smtp smtps telnet tftp ws wss
Features: alt-svc AsynchDNS HSTS HTTPS-proxy IPv6 Largefile libz NTLM PSL SSL threadsafe TLS-SRP UnixSockets

  接着回到git目录下,重新编译

[root@localhost curl-8.18.0]# cd ../git-2.49.1
[root@localhost git-2.49.1]# ./configure --with-curl=/usr/local/curl-8.18.0 --prefix=/usr/local/git-2.49.1
[root@localhost git-2.49.1]# echo $?  #检查上一个命令是否有异常
0
[root@localhost git-2.49.1]# make all doc info
/bin/sh: docbook2x-texi: command not found
make[1]: *** [user-manual.texi] Error 127
make[1]: Leaving directory `/root/git-2.49.1/Documentation'
make: *** [info] Error 2

  此时可以看到会报错"docbook2x-texi: command not found",我查了一圈发现,实际上已经安装(docbook2X),这里只需要设置一个软链接。

[root@localhost git-2.49.1]# ln -s /usr/bin/db2x_docbook2texi /usr/bin/docbook2x-texi

  之后,重新执行"make all doc info",并继续安装

[root@localhost git-2.49.1]# make all doc info

[root@localhost git-2.49.1]# echo $?    #检查上一个命令是否有异常
0
[root@localhost git-2.49.1]# make install install-doc install-html install-info
[root@localhost git-2.49.1]# echo $?    #检查上一个命令是否有异常
0
[root@localhost git-2.49.1]# echo "export PATH=/usr/local/git-2.49.1/bin:$PATH" >>/etc/profile  #添加环境变量
[root@localhost git-2.49.1]# source /etc/profile
[root@localhost git-2.49.1]# git --version  #查看版本是否正确
git version 2.49.1

  以上就安装好了。

(4).配置服务器仓库

  我个人认为一般会存在两种情况:1、先开发后搭建git服务器(这个情况我估计应该少很多了);2、先搭建git服务器后开发

  其他的先不说,先在服务器上新建一个git专属用户,专门管理git。

[root@localhost ~]# groupadd git
[root@localhost ~]# useradd git -g git
[root@localhost ~]# passwd git
Changing password  for user git.
New password: 
Retype  new password: 
passwd: all authentication tokens updated successfully.

  a.第一种情况模拟,我在个人的window系统上创建一个my_project目录,并在其中新增test1.txt、test2.sql。

    目录空白位置右键,点击”Open Git Bash Here“,打开命令行工具。然后执行如下命令:

$ git config --global user.name "John Doe"    #配置用户名

64267@LAPTOP-TDH6F977 MINGW64 ~/Desktop/my_project (master)
$ git config --global user.email johndoe@example.com    #配置邮箱地址

64267@LAPTOP-TDH6F977 MINGW64 ~/Desktop/my_project (master)
$ git init  #初始化仓库
hint: Using 'master' as the name for the initial branch. This default branch name
hint: will change to "main" in Git 3.0. To configure the initial branch name
hint: to use in all of your new repositories, which will suppress this warning,
hint: call:
hint:
hint:   git config --global init.defaultBranch <name>
hint:
hint: Names commonly chosen instead of 'master' are 'main', 'trunk' and
hint: 'development'. The just-created branch can be renamed via this command:
hint:
hint:   git branch -m <name>
hint:
hint: Disable this message with "git config set advice.defaultBranchName false"
Initialized empty Git repository in C:/Users/64267/Desktop/my_project/.git/

64267@LAPTOP-TDH6F977 MINGW64 ~/Desktop/my_project (master)
$ ll -a
total 8
drwxr-xr-x 1 64267 197609 0 Jan 14 21:14 ./
drwxr-xr-x 1 64267 197609 0 Jan 14 21:12 ../
drwxr-xr-x 1 64267 197609 0 Jan 14 21:14 .git/
-rw-r--r-- 1 64267 197609 0 Jan 14 20:56 test1.txt
-rw-r--r-- 1 64267 197609 0 Jan 14 20:56 test2.sql

64267@LAPTOP-TDH6F977 MINGW64 ~/Desktop/my_project (master)
$ git status    #查看状态
On branch master

No commits yet

Untracked files:    #未跟踪的文件
  (use  "git add ..." to include  in what will be committed)
        test1.txt
        test2.sql

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

64267@LAPTOP-TDH6F977 MINGW64 ~/Desktop/my_project (master)
$ git add .  #将当前目录下所有文件进行跟踪,也可以跟随文件名进行单点添加

64267@LAPTOP-TDH6F977 MINGW64 ~/Desktop/my_project (master)
$ git status    #查看状态
On branch master

No commits yet

Changes to be committed:    #要提交的更改
  (use  "git rm --cached ..." to unstage)
        new file:   test1.txt
        new file:   test2.sql


64267@LAPTOP-TDH6F977 MINGW64 ~/Desktop/my_project (master)
$ git commit -m  'initial project version'   #提交并备注
[master (root-commit) 59a2071] initial project version
 2 files changed, 0 insertions(+), 0 deletions(-)
 create mode 100644 test1.txt
 create mode 100644 test2.sql

64267@LAPTOP-TDH6F977 MINGW64 ~/Desktop/my_project (master)
$ cd ..  #返回上一层

64267@LAPTOP-TDH6F977 MINGW64 ~/Desktop
$ git clone --bare my_project my_project.git  #克隆一个裸仓
Cloning  into bare repository  'my_project.git' ...
done.

64267@LAPTOP-TDH6F977 MINGW64 ~/Desktop
$ scp -r my_project.git git@[服务器地址]:/home/git/my_project.git  #将裸仓上传至服务器端
The authenticity of host '192.168.142.101 (192.168.142.101)' can't be established.
ED25519 key fingerprint is: SHA256:G5Bqj7K2SG1CGxyk4p4AyCWqBOe+9fxRBG8hpZVb0vE
This key is not known by any other names.
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
Warning: Permanently added '192.168.142.101' (ED25519) to the list of known hosts.
** WARNING: connection is not using a post-quantum key exchange algorithm.
** This session may be vulnerable to "store now, decrypt later" attacks.
** The server may need to be upgraded. See https://openssh.com/pq.html
git@192.168.142.101's password:
config                                                                                   100%  163    96.0KB/s   00:00
description                                                                              100%   73    85.2KB/s   00:00
HEAD                                                                                     100%   23    32.4KB/s   00:00
applypatch-msg.sample                                                                    100%  478   810.7KB/s   00:00
commit-msg.sample                                                                        100%  896     1.5MB/s   00:00
fsmonitor-watchman.sample                                                                100% 4726     6.2MB/s   00:00
post-update.sample                                                                       100%  189   246.2KB/s   00:00
pre-applypatch.sample                                                                    100%  424   595.8KB/s   00:00
pre-commit.sample                                                                        100% 1649     2.2MB/s   00:00
pre-merge-commit.sample                                                                  100%  416   552.3KB/s   00:00
pre-push.sample                                                                          100% 1374     1.6MB/s   00:00
pre-rebase.sample                                                                        100% 4898     1.4MB/s   00:00
pre-receive.sample                                                                       100%  544   820.3KB/s   00:00
prepare-commit-msg.sample                                                                100% 1492     1.9MB/s   00:00
push-to-checkout.sample                                                                  100% 2783     3.8MB/s   00:00
sendemail-validate.sample                                                                100% 2308     2.0MB/s   00:00
update.sample                                                                            100% 3650     4.9MB/s   00:00
exclude                                                                                  100%  240   443.0KB/s   00:00
54ae5be93c6478b2da71e5e142adb156cc07ef                                                   100%   64   111.2KB/s   00:00
49973e2e839000f52a02e7c9f0e936cf7258c8                                                   100%  137   197.3KB/s   00:00
9de29bb2d1d6434b8b29ae775ad8c2e48c5391                                                   100%   15     7.2KB/s   00:00
packed-refs                                                                              100%  105   161.6KB/s   00:00

64267@LAPTOP-TDH6F977 MINGW64 ~/Desktop

    到服务器上看下,裸仓是否存在。

[root@localhost ~]# su git
[git@localhost root]$ cd
[git@localhost ~]$ ll
total 0
drwxr-xr-x. 6 git git 122 Jan 14 21:34 my_project.git
[git@localhost ~]$ ls my_project.git/
config  description  HEAD  hooks  info  objects  packed-refs  refs

    这就完成了,下面我们做一下测试。将my_project目录下的文件删除,接着从服务器上将文件clone下来。(还是接着上面的window命令行,我们当前的地址是在~/Desktop/目录下)

$ cd my_project

64267@LAPTOP-TDH6F977 MINGW64 ~/Desktop/my_project (master)
$ rm -rf .git/

64267@LAPTOP-TDH6F977 MINGW64 ~/Desktop/my_project
$ rm -rf test1.txt test2.sql

64267@LAPTOP-TDH6F977 MINGW64 ~/Desktop/my_project
$ ll -a
total 4
drwxr-xr-x 1 64267 197609 0 Jan 14 21:43 ./
drwxr-xr-x 1 64267 197609 0 Jan 14 21:27 ../

64267@LAPTOP-TDH6F977 MINGW64 ~/Desktop/my_project
$ cd ..

64267@LAPTOP-TDH6F977 MINGW64 ~/Desktop
$ git clone git@192.168.142.101:my_project.git
Cloning into 'my_project'...
** WARNING: connection is not using a post-quantum key exchange algorithm.
** This session may be vulnerable to "store now, decrypt later" attacks.
** The server may need to be upgraded. See https://openssh.com/pq.html
git@192.168.142.101's password:
remote: Counting objects: 3, done.
remote: Compressing objects: 100% (2/2), done.
remote: Total 3 (delta 0), reused 0 (delta 0)
Receiving objects: 100% (3/3), done.

64267@LAPTOP-TDH6F977 MINGW64 ~/Desktop
$ cd my_project

64267@LAPTOP-TDH6F977 MINGW64 ~/Desktop/my_project (master)
$ ls -a
./  ../  .git/  test1.txt  test2.sql

64267@LAPTOP-TDH6F977 MINGW64 ~/Desktop/my_project (master)

    测试完美通过。

  b.第二种情况模拟,这种情况才是大多数情况,并且由于工具的普及,直接敲代码的情况可能已经较少了。

    直接在服务器上创建裸仓。

[git@localhost ~]$ pwd
/home/git
[git@localhost ~]$ git init --bare my_project2.git
Initialized empty Git repository in /home/git/my_project2.git/
[git@localhost ~]$ ls
my_project2.git  my_project.git
[git@localhost ~]$ ls my_project2.git/
branches  config  description  HEAD  hooks  info  objects  refs

    本地直接clone,之后进行开发

$ pwd
/c/Users/64267/Desktop/my_project

64267@LAPTOP-TDH6F977 MINGW64 ~/Desktop/my_project (master)
$ cd ..

64267@LAPTOP-TDH6F977 MINGW64 ~/Desktop
$ git clone git@192.168.142.101:my_project2.git
Cloning into 'my_project2'...
** WARNING: connection is not using a post-quantum key exchange algorithm.
** This session may be vulnerable to "store now, decrypt later" attacks.
** The server may need to be upgraded. See https://openssh.com/pq.html
git@192.168.142.101's password:
warning: You appear to have cloned an empty repository.
hint: Using 'master' as the name for the initial branch. This default branch name
hint: will change to "main" in Git 3.0. To configure the initial branch name
hint: to use in all of your new repositories, which will suppress this warning,
hint: call:
hint:
hint:   git config --global init.defaultBranch <name>
hint:
hint: Names commonly chosen instead of 'master' are 'main', 'trunk' and
hint: 'development'. The just-created branch can be renamed via this command:
hint:
hint:   git branch -m <name>
hint:
hint: Disable this message with "git config set advice.defaultBranchName false"

64267@LAPTOP-TDH6F977 MINGW64 ~/Desktop
$ cd my_project2/

64267@LAPTOP-TDH6F977 MINGW64 ~/Desktop/my_project2 (master)
$ ll -a
total 8
drwxr-xr-x 1 64267 197609 0 Jan 14 21:48 ./
drwxr-xr-x 1 64267 197609 0 Jan 14 21:48 ../
drwxr-xr-x 1 64267 197609 0 Jan 14 21:48 .git/

64267@LAPTOP-TDH6F977 MINGW64 ~/Desktop/my_project2 (master)

(5).传输协议的相关配置

  Git可以使用四种不同的协议来传输资料:本地协议(Local),HTTP 协议,SSH(Secure Shell)协议及 Git 协议。 它们各有优缺点,但据我所知多数情况下采用SSH协议或HTTP协议。优缺点详见官方文档:https://git-scm.com/book/zh/v2/%e6%9c%8d%e5%8a%a1%e5%99%a8%e4%b8%8a%e7%9a%84-Git-%e5%8d%8f%e8%ae%ae

  1)SSH协议上面已经用到了,但是实际情况下,并不会将服务器密码告知开发人员,此时就需要SSH公私钥对。

    首先,你需要确认个人是否已经拥有密钥。 默认情况下,用户的 SSH 密钥存储在其 ~/.ssh 目录下。还是通过Window上的git_bash,进入该目录并列出其中内容,你便可以快速确认自己是否已拥有密钥:

$ cd ~/.ssh/

64267@LAPTOP-TDH6F977 MINGW64 ~/.ssh
$ ls -a
./  ../  id_ed25519  id_ed25519.pub  known_hosts  known_hosts.old

    其中id_ed25529和id_ed25519.pub就是一对公私钥对,.pub文件为本地的公钥,对应的另一个为私钥。 如果找不到这样的文件(或者根本没有 .ssh 目录),你可以通过运行 ssh-keygen 程序来创建它们。 在 Linux/macOS 系统中,ssh-keygen 随 SSH 软件包提供;在 Windows 上,该程序包含于 MSysGit 软件包中。我这里使用的是Windows系统,git_bash的命令行:

$ ssh-keygen.exe -o
Generating  public / private ed25519 key pair.
Enter file  in which to save the key (/c/Users/64267/.ssh/id_ed25519):
Enter passphrase  for "/c/Users/admin/.ssh/id_ed25519" (empty  for no passphrase):
Enter same passphrase again:
Your identification has been saved  in /c/Users/admin/.ssh/id_ed25519
Your  public key has been saved  in /c/Users/admin/.ssh/id_ed25519.pub
The key fingerprint  is :
SHA256:cUJipY/OfsEfq25aCOh+34O1KT79Ya/3KG4eTe883SQ admin@DESKTOP-4CERLUK
The key's randomart image  is :
+--[ED25519 256]--+
|      o.o        |
|     . +         |
|      . o .      |
|   .   o +       |
|  . . ..S   .    |
| .   + .+ .o .E .|
|  .   ++.=+o. .+.|
| .  ..+oB.=+.+. o|
|  .. o=B+B=+o.+. |
+----[SHA256]-----+
64267@LAPTOP-TDH6F977 MINGW64 ~/Desktop/my_project2 (master)

    ssh-keygen 会确认密钥的存储位置(默认是 .ssh/id_rsa),然后它会要求你输入两次密钥口令。 如果你不想在使用密钥时输入口令,将其留空即可。 然而,如果你使用了密码,那么请确保添加了 -o 选项,它会以比默认格式更能抗暴力破解的格式保存私钥。 你也可以用 ssh-agent 工具来避免每次都要输入密码。

    接着将公钥配置到服务器上。注意:我们在原本的公钥前面添加 no-port-forwarding,no-X11-forwarding,no-agent-forwarding,no-pty 用来限制ssh端口转发访问服务器

[git@localhost ~]$ mkdir .ssh
[git@localhost ~]$ chmod 700 .ssh
[git@localhost ~]$ touch .ssh/authorized_keys
[git@localhost ~]$ chmod 600 .ssh/authorized_keys
[git@localhost ~]$ vim .ssh/authorized_keys
no-port-forwarding,no-X11-forwarding,no-agent-forwarding,no-pty [公钥内容]

    进行测试,将Windows电脑上的my_project目录删除,重新clone:

$ cd

64267@LAPTOP-TDH6F977 MINGW64 ~
$ git clone git@[服务器地址]:my_project
Cloning  into 'my_project' ...
** WARNING: connection is not using a post-quantum key exchange algorithm.
** This session may be vulnerable to "store now, decrypt later" attacks.
** The server may need to be upgraded. See https://openssh.com/pq.html
remote: Counting objects: 3, done.  #可以看到直接开始clone,不需要输入密码了
remote: Compressing objects: 100% (2/2), done.
remote: Total 3 (delta 0), reused 0 (delta 0)
Receiving objects: 100% (3/3), done.

64267@LAPTOP-TDH6F977 MINGW64 ~

    注意:目前测试是通过了,但是也造成了开发人员可以免密登录服务器,所以还需要进行进一步的设置。

    借助一个名为 git-shell 的受限 shell 工具,你可以方便地将用户 git 的活动限制在与 Git 相关的范围内。 该工具随 Git 软件包一同提供。如果将 git-shell 设置为用户 git 的登录 shell(login shell), 那么该用户便不能获得此服务器的普通 shell 访问权限。 若要使用 git-shell,需要用它替换掉 bash 或 csh,使其成为该用户的登录 shell。为进行上述操作,首先你必须确保 git-shell 的完整路径名已存在于 /etc/shells 文件中,如果没有就添加一下。

[root@localhost ~]# cat /etc/shells
/bin/sh
/bin/bash
/usr/bin/sh
/usr/bin/bash
[root@localhost ~]# which git-shell
/usr/bin/git-shell
[root@localhost ~]# echo '/usr/bin/git-shell' >> /etc/shells

    确认没有问题后才可以使用 chsh <username> -s <shell> 命令修改系统用户的 默认登录shell。或者直接vim /etc/passwd,将git用户登录模式改为/usr/bin/git-shell。

[root@localhost ~]# chsh git -s $(which git-shell)    #我这里与chsh git -s /usr/bin/git-shell等价
Changing shell  for git.
Shell changed.

    最后测试一下是否被限制。在windows系统上使用git的命令行尝试。

$ ssh git@[服务器地址]
** WARNING: connection is not using a post-quantum key exchange algorithm.
** This session may be vulnerable to "store now, decrypt later" attacks.
** The server may need to be upgraded. See https://openssh.com/pq.html
PTY allocation request failed on channel 0
fatal: Interactive git shell is not enabled.
hint: ~/git-shell-commands should exist and have read and execute access.
Connection to 192.168.142.101 closed.

64267@LAPTOP-TDH6F977 MINGW64 ~

  2)HTTP协议

    我们一般通过SSH进行授权访问,通过git://进行无授权访问,但HTTP协议可以同时实现以上两种方式的访问。而配置一个轻量级http服务器一般只需要在服务器上启动Git自带的名为git-http-backend的CGI脚本。该 CGI 脚本将会读取由 git fetch 或 git push 命令向 HTTP URL 发送的请求路径和头部信息, 来判断该客户端是否支持 HTTP 通信(不低于 1.6.6 版本的客户端支持此特性)。如果 CGI 发现该客户端支持智能(Smart)模式,它将会以智能模式与它进行通信, 否则它将会回落到哑(Dumb)模式下(因此它可以对某些老的客户端实现向下兼容)。

    这里采用Apache来作为CGI服务器,如果没有Apache可以执行如下命令:

[root@localhost ~]# dnf -y install httpd httpd-tools
[root@localhost ~]# httpd -M | grep -E  'cgi|alias|env'   #查看Apache启用模块
AH00558: httpd: Could not reliably determine the server 's fully qualified domain name, using ::1. Set the ' ServerName' directive globally to suppress  this message
 alias_module (shared)
 env_module (shared)
 setenvif_module (shared)
 vhost_alias_module (shared)
 proxy_fcgi_module (shared)
 proxy_scgi_module (shared)
 cgi_module (shared)
#如果缺少以上任意一种可以使用以下命令安装
[root@localhost ~]# dnf -y install cgi_module alias_module env_module

    该操作将会启用 cgi_module, alias_module 和 env_module 等 Apache 模块, 这些模块都是使该功能正常工作所必须的。

    还要将裸仓的上级目录(例如上文中的/home/git)的用户组设置为apache(注意:这里是apache的用户组,不同系统可能不一样),这样 Web 服务器才能读写该仓库, 因为运行 CGI 脚本的 Apache 实例默认会以该用户的权限运行。因为这里不用ssh认证,所以我将裸仓的上级目录改到/srv/git,操作如下:

[root@localhost ~]# mkdir -p /srv/git

    接着修改Apache的配置文件,我这里直接新增一个配置文件到/etc/httpd/conf.d/目录下,因为/etc/httpd/conf/httpd.conf中存在"IncludeOptional conf.d/*.conf"(IncludeOptional引用的路径有问题时会被忽略,不会报错)引用了/etc/httpd/conf.d/目录下所有.conf文件。命令如下:

[root@localhost ~]# vim /etc/httpd/conf.d/git.conf
# 监听8989端口
Listen 8989

    # git仓库路径设置
    SetEnv GIT_PROJECT_ROOT /srv/git
    # 仓库公开策略。如果没有下面这一行,那么无授权客户端只能访问带 git-daemon-export-ok 文件的版本库;如果有,那么Git将会公开服务器上所有的仓库
    SetEnv GIT_HTTP_EXPORT_ALL
    # 将以/git/开头的请求映射到git-http-backend这个CGI脚本
    ScriptAlias /git/ /usr/libexec/git-core/git-http-backend/
    # 匹配目录
    <directory "/usr/libexec/git-core">
        # 匹配文件名
        <files "git-http-backend">
            # 用户认证类型
            AuthType Basic
            # 设置授权领域的名称
            AuthName  "Git Access"
            # 设置用于身份验证的用户的账号密码地址
            AuthUserFile /srv/git/.htpasswd
            Require expr !(%{QUERY_STRING} -strmatch  '*service=git-receive-pack*' || %{REQUEST_URI} =~ m#/git-receive-pack$#)
            # 强制用户必须身份验证才能访问受保护的资源
            Require valid-user
        </files>
    </directory>
    <directory "/srv/git">
        #启用 CGI 脚本的执行权限
        Options +ExecCGI
        #忽略.htaccess 文件
        AllowOverride None
        #授权所有用户访问当前目录下的所有文件
        Require all granted
    </directory>

[root@localhost ~]# systemctl restart httpd

    注意:不同系统git-http-backend的CGI脚本路径可能不一样,根据实际情况修改。CentOS是/usr/libexec/git-core/git-http-backend,有些liinux系统是/usr/lib/git-core/git-http-backend。

    Require expr !(%{QUERY_STRING} -strmatch '*service=git-receive-pack*' || %{REQUEST_URI} =~ m#/git-receive-pack$#) 配置说明:

      %{QUERY_STRING} 这是HTTP请求的查询字符串部分,即URL中问号后面的参数部分;

      %{QUERY_STRING} -strmatch '*service=git-receive-pack*' 这部分表示查询字符串中是否包含`service=git-receive-pack`。`-strmatch`表示字符串匹配,`*service=git-receive-pack*`表示允许前后有任意字符的匹配条件;

      || 这是逻辑或操作符,表示两个条件中的任意一个满足即可;

      %{REQUEST_URI} =~ m#/git-receive-pack$# 这部分检查请求的URI(路径部分)是否以`/git-receive-pack`结尾。`=~`表示正则表达式匹配,`m#...#`是正则表达式的模式,而`$`表示匹配字符串的末尾。

      因此,整个 Require 表达式的含义是:仅当查询字符串包含`service=git-receive-pack`或URI以`/git-receive-pack`结尾时,这部分规则才会被触发。(即在上传时需要进行身份验证

    更多Apache授权访问配置请查看官网文档:https://httpd.apache.org/docs/current/howto/auth.html

    创建一个授权账号,如下:

[root@localhost ~]# htpasswd -c /srv/git/.htpasswd testuser
New password: 
Re-type  new password: 
Adding password  for user testuser
[root@localhost ~]# chgrp apache /srv/git/.htpasswd

    创建仓库便于进行测试:

[root@localhost conf]# cd /srv/git/
[root@localhost git]# git init --bare my_project3.git  #创建裸仓
Initialized empty Git repository  in /srv/git/my_project3.git/
[root@localhost git]# git init --bare my_project4.git  #创建无授权客户可以访问的裸仓
Initialized empty Git repository  in /srv/git/my_project4.git/
[root@localhost git]# touch my_project4.git/git-daemon-export-ok
#也可以chown -R apache:apache /srv/git将个人与组都改为apache
[root@localhost git]# chgrp -R apache /srv/git
[root@localhost git]# chmod -R g+w /srv/git/
[root@localhost git]# ll
total 0
drwxrwxr-x. 7 root apache 119 Jan 14 22:58 my_project3.git
drwxrwxr-x. 7 root apache 147 Jan 14 22:58 my_project4.git

    将服务器端 /etc/httpd/conf.d/git.conf 配置文件中的 "SetEnv GIT_HTTP_EXPORT_ALL"删除或注释,之后进行clone测试(Windows客户端):

64267@LAPTOP-TDH6F977 MINGW64 ~/Desktop
$ git clone http://[服务器地址]:8989/git/my_project3.git
Cloning into 'my_project3'...
fatal: repository 'http://192.168.142.101:8989/git/my_project3.git/' not found

64267@LAPTOP-TDH6F977 MINGW64 ~/Desktop
$ git clone http://[服务器地址]:8989/git/my_project4.git
Cloning into 'my_project4'...
warning: You appear to have cloned an empty repository.
hint: Using 'master' as the name for the initial branch. This default branch name
hint: will change to "main" in Git 3.0. To configure the initial branch name
hint: to use in all of your new repositories, which will suppress this warning,
hint: call:
hint:
hint:   git config --global init.defaultBranch <name>
hint:
hint: Names commonly chosen instead of 'master' are 'main', 'trunk' and
hint: 'development'. The just-created branch can be renamed via this command:
hint:
hint:   git branch -m <name>
hint:
hint: Disable this message with "git config set advice.defaultBranchName false"

64267@LAPTOP-TDH6F977 MINGW64 ~/Desktop

    可以看到my_project3无法找到,但my_project4正常clone,接着将配置还原,再试一次:

$ rm -rf my_project4/

64267@LAPTOP-TDH6F977 MINGW64 ~/Desktop
$ git clone http://[服务器地址]:8989/git/my_project3.git
Cloning into 'my_project3'...
warning: You appear to have cloned an empty repository.
hint: Using 'master' as the name for the initial branch. This default branch name
hint: will change to "main" in Git 3.0. To configure the initial branch name
hint: to use in all of your new repositories, which will suppress this warning,
hint: call:
hint:
hint:   git config --global init.defaultBranch <name>
hint:
hint: Names commonly chosen instead of 'master' are 'main', 'trunk' and
hint: 'development'. The just-created branch can be renamed via this command:
hint:
hint:   git branch -m <name>
hint:
hint: Disable this message with "git config set advice.defaultBranchName false"

64267@LAPTOP-TDH6F977 MINGW64 ~/Desktop
$ git clone http://[服务器地址]:8989/git/my_project4.git
Cloning into 'my_project4'...
warning: You appear to have cloned an empty repository.
hint: Using 'master' as the name for the initial branch. This default branch name
hint: will change to "main" in Git 3.0. To configure the initial branch name
hint: to use in all of your new repositories, which will suppress this warning,
hint: call:
hint:
hint:   git config --global init.defaultBranch <name>
hint:
hint: Names commonly chosen instead of 'master' are 'main', 'trunk' and
hint: 'development'. The just-created branch can be renamed via this command:
hint:
hint:   git branch -m <name>
hint:
hint: Disable this message with "git config set advice.defaultBranchName false"

64267@LAPTOP-TDH6F977 MINGW64 ~/Desktop

    再进行push测试,git push时会从弹出输入账号密码的界面,如下图:

$ echo  "my_project3" > my_project3/file.txt

64267@LAPTOP-TDH6F977 MINGW64 ~/Desktop
$ cd my_project3/

64267@LAPTOP-TDH6F977 MINGW64 ~/Desktop/my_project3 (master)
$ git add .
warning: in the working copy of 'file.txt', LF will be replaced by CRLF the next time Git touches it

64267@LAPTOP-TDH6F977 MINGW64 ~/Desktop/my_project3 (master)
$ git commit -m  "Initial commit"
[master (root-commit) eacb335] Initial commit
 1 file changed, 1 insertion(+)
 create mode 100644 file.txt

64267@LAPTOP-TDH6F977 MINGW64 ~/Desktop/my_project3 (master)
$ git push
Enumerating objects: 3, done.
Counting objects: 100% (3/3), done.
Writing objects: 100% (3/3), 225 bytes | 225.00 KiB/s, done.
Total 3 (delta 0), reused 0 (delta 0), pack-reused 0 (from 0)
To http://[服务器地址]:8989/git/my_project3.git
 * [new branch]      master -> master

64267@LAPTOP-TDH6F977 MINGW64 ~/Desktop/my_project3 (master)

  这样就完成了。

 

  

 

    

参考资料:https://www.cnblogs.com/Kyle023/p/14746741.html

     https://blog.csdn.net/GTOFEI013/article/details/89519104

     https://blog.csdn.net/weixin_30570101/article/details/95021329

       https://www.cnblogs.com/Undefined443/p/18524222

posted @ 2024-10-16 20:35  苦逼运维  阅读(336)  评论(0)    收藏  举报