版本管理之gitlab实践教程:基础篇(14)

这篇文章整理一下对gitlab/github进行clone或者push操作时,不需要每次提交都输入用户名/密码的几种方式。

场景

何时需要输入用户名/密码

gitlab可以创建private/protected/public的仓库,private的仓库,在git clone执行时会提示输入用户名/密码,以确认此用户是否有权限。

何时希望不输入用户名/密码

交互方式需要中断程序运行,如果此项操作是在CI集成的脚本中被自动调用,往往希望能够提供自动交互方式。

解决方式

方式1: SSH设定

使用场景:
远端仓库为gitlab,客户端使用git,通过使用ssh-key的设定,来实现对private仓库的git clone的免密码。

方式2: 活用git的多种方式中包含用户名/密码的方式

使用场景
使用git clone http://用户名:密码@机器名:port/groupname/project.git方式进行操作,因为密码和用户名已经提供,自然不必再输入

方式3: 设定.git-credentials

使用场景:
通过设定不同层次的.git-credentials来设定用户名/密码

方式4: 设定config

使用场景:
通过设定不同层次的config文件来设定用户名/密码

方式5: 在remote中加入用户名/密码

使用场景:
通过对git的remote进行设定使其包含用户名/密码来实现git push等操作时无需再次输入用户名密码

事前准备

以下使用rest api方式进行准备,如果使用gitlab的界面操作,登录进去创建一个private的仓库即可。

获取使用token

gitlab相关信息如下:

设定 详细
gitlab版本 8.12.9
gitlab连接URL http://192.168.163.118:32001
实验用Token 9-9rh18mQz4h3eDMQf5M
[root@platform tmp]# curl http://192.168.163.118:32001/api/v3/session --data 'login=root&password=12345678' 2>/dev/null |jq . |grep token 
  "private_token": "9-9rh18mQz4h3eDMQf5M"
[root@platform tmp]#

创建项目

[root@platform ~]# curl --request POST --header "PRIVATE-TOKEN: 9-9rh18mQz4h3eDMQf5M" --data "name=demotest" "http://192.168.163.118:32001/api/v3/projects" |jq .
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100  1444  100  1431  100    13    671      6  0:00:02  0:00:02 --:--:--   671
{
  "id": 2,
  "description": null,
  "default_branch": null,
  "tag_list": [],
  "public": false,
  "archived": false,
  "visibility_level": 0,
  "ssh_url_to_repo": "git@1c79a0cf3ed8:root/demotest.git",
  "http_url_to_repo": "http://1c79a0cf3ed8/root/demotest.git",
  "web_url": "http://1c79a0cf3ed8/root/demotest",
  "owner": {
    "name": "Administrator",
    "username": "root",
    "id": 1,
    "state": "active",
    "avatar_url": "http://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=80&d=identicon",
    "web_url": "http://1c79a0cf3ed8/u/root"
  },
  "name": "demotest",
  "name_with_namespace": "Administrator / demotest",
  "path": "demotest",
  "path_with_namespace": "root/demotest",
  "container_registry_enabled": true,
  "issues_enabled": true,
  "merge_requests_enabled": true,
  "wiki_enabled": true,
  "builds_enabled": true,
  "snippets_enabled": true,
  "created_at": "2018-07-30T08:57:42.975Z",
  "last_activity_at": "2018-07-30T08:57:42.975Z",
  "shared_runners_enabled": true,
  "lfs_enabled": true,
  "creator_id": 1,
  "namespace": {
    "id": 1,
    "name": "root",
    "path": "root",
    "owner_id": 1,
    "created_at": "2018-07-29T22:13:42.122Z",
    "updated_at": "2018-07-29T22:13:42.122Z",
    "description": "",
    "avatar": null,
    "share_with_group_lock": false,
    "visibility_level": 20,
    "request_access_enabled": true,
    "deleted_at": null,
    "lfs_enabled": null
  },
  "avatar_url": null,
  "star_count": 0,
  "forks_count": 0,
  "open_issues_count": 0,
  "runners_token": "RJVU4HPv6ug-bkPNzKyh",
  "public_builds": true,
  "shared_with_groups": [],
  "only_allow_merge_if_build_succeeds": false,
  "request_access_enabled": true
}
[root@platform ~]#

或者直接在gitlab上创建一个私有的仓库
版本管理之gitlab实践教程:基础篇(14)_第1张图片

现象

因为是私有仓库,缺省设定下,git clone需要输入用户名/密码

[root@platform ~]# git clone http://192.168.163.118:32001/root/demotest.git
Cloning into 'demotest'...
Username for 'http://192.168.163.118:32001':

设定

方式1: SSH设定

使用场景:
远端仓库为gitlab,客户端使用git,通过使用ssh-key的设定,来实现对private仓库的git clone的免密码。

设定客户端ssh-key

使用ssh-keygen生成缺省的rsa方式的密码对

[root@platform ~]# ssh-keygen
Generating public/private rsa key pair.
Enter file in which to save the key (/root/.ssh/id_rsa): 
Enter passphrase (empty for no passphrase): 
Enter same passphrase again: 
Your identification has been saved in /root/.ssh/id_rsa.
Your public key has been saved in /root/.ssh/id_rsa.pub.
The key fingerprint is:
SHA256:z4LsUjifKSVJD2mZhTIfv1rPyAOD2yN+zX7A9OUBQto root@platform
The key's randomart image is:
+---[RSA 2048]----+
|     o.          |
|  o ooo .        |
|   +.BE. .       |
|    O o   o      |
|   + B oSo .     |
|  . B.O..o.      |
|   o #oB. o      |
|  o B.X +.       |
| ..o =oo         |
+----[SHA256]-----+
[root@platform ~]#

将生成的rsa公钥id_rsa.pub,添加到gitlab中

[root@platform ~]# cat /root/.ssh/id_rsa.pub
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDgF7YowO3D+ow6PQ54iu5LU93NlZ19sQlKnbH1dp+pKb/hNh7hnj4aVkDtrTrFnYBULGgmQU8Z1hd9zZT5sAaWUAOiloilT/Kj6qhvf1N7QDmT0Dq3pA3WkBuk7n9RjzqLUfFx79jpR1LBh41qUjEtyClOzw9523Wf9PV1eveHrwcNItEHYoh9aMSa44EGDba2JMVeCNw8p2x+I2fOwFy7WGaEFFydMo3hJkvaoiVZ0ND/k+adaNSViXA3Nm1blMd+dnQ++uqjdjGJYVvlrXm1epmb1d6+BL2y1ro2NqetJ88Jp860/Aw+YZt8ildSYt0a2hD1a7VF7a9W6cvvgc4T root@platform
[root@platform ~]#

在gitlab的profile settings的ssh keys的选项页,将上述公钥输入,并点击add key按钮
版本管理之gitlab实践教程:基础篇(14)_第2张图片

这种方式就是基于ssh的通道进行的,也是使用最多的方式之一,当然在不同的环境下可能还有其他的一些问题,这里不再赘述。

方式2: 活用git的多种方式中包含用户名/密码的方式

使用场景
使用git clone http://用户名:密码@机器名:port/groupname/project.git方式进行操作,因为密码和用户名已经提供,自然不必再输入

[root@platform ~]# git clone http://192.168.163.118:32001/root/demotest.git
Cloning into 'demotest'...
Username for 'http://192.168.163.118:32001': ^C
[root@platform ~]# git clone http://root:[email protected]:32001/root/demotest.git
Cloning into 'demotest'...
warning: You appear to have cloned an empty repository.
[root@platform ~]#

可以看到这种方式也可以直接clone了,问题之一就在于密码的明文显示,如果你不是那么纠结,这种方式是最简单的了。
其实这种方式也是通过修改config的设定起到作用的,可以看到设定的信息在config的url中有保存,所以后面才不需要重新输入密码。

[root@platform ~]# cd demotest
[root@platform demotest]# cd .git
[root@platform .git]# ls
HEAD  branches  config  description  hooks  info  objects  refs
[root@platform .git]# cat config
[core]
    repositoryformatversion = 0
    filemode = true
    bare = false
    logallrefupdates = true
[remote "origin"]
    url = http://root:12345678@192.168.163.118:32001/root/demotest.git
    fetch = +refs/heads/*:refs/remotes/origin/*
[branch "master"]
    remote = origin
    merge = refs/heads/master
[root@platform .git]#

方式3: 设定.git-credentials

使用场景:
通过设定不同层次的.git-credentials来设定用户名/密码
就像git的config文件一样,分成系统级/用户级/项目级三层,.git-credentials也是一样。
这里使用用户级的设定,执行日志如下所示:

[root@platform ~]# touch ~/.git-credentials
[root@platform ~]# echo "http://root:[email protected]:32001" >~/.git-credentials
[root@platform ~]# git config --global credential.helper store
[root@platform ~]#

执行对私有仓库git clone可以不必输入密码,这种方式是通过.git-credentials来进行的

[root@platform ~]# git clone http://192.168.163.118:32001/root/demotest.git
Cloning into 'demotest'...
warning: You appear to have cloned an empty repository.
[root@platform ~]#

这种的好处是每次提交的时候不必看见明文的密码了,但是还是有保存。
破坏一下这种设定

[root@platform ~]# git config --global credential.helper get
[root@platform ~]# git clone http://192.168.163.118:32001/root/demotest.git
fatal: destination path 'demotest' already exists and is not an empty directory.
[root@platform ~]# rm -rf demotest/
[root@platform ~]# git clone http://192.168.163.118:32001/root/demotest.git
Cloning into 'demotest'...
git: 'credential-get' is not a git command. See 'git --help'.
Username for 'http://192.168.163.118:32001':

删除刚刚生成的用户级文件

[root@platform ~]# rm ~/.git-credentials 
rm: remove regular file '/root/.git-credentials'? y
[root@platform ~]# 

另外,用户级别的~/.gitconfig文件中也生成了如下的信息

[root@platform ~]# cat ~/.gitconfig 
[user]
    email = liumiaocn@outlook.com
    name = Liu Miao
[credential]
    helper = get
[root@platform ~]#

删除credential相关的设定,就基本清场完毕了

[root@platform ~]# cat ~/.gitconfig 
[user]
    email = liumiaocn@outlook.com
    name = Liu Miao
[root@platform ~]# 

方式4: 设定config

使用场景:
通过设定不同层次的config文件来设定用户名/密码

先通过用户名和密码方式进行clone

[root@platform ~]# git clone http://192.168.163.118:32001/root/demotest.git
Cloning into 'demotest'...
Username for 'http://192.168.163.118:32001': root
Password for 'http://[email protected]:32001': 
warning: You appear to have cloned an empty repository.
[root@platform ~]#

添加一个文件并push会需要输入用户名/密码

[root@platform ~]# cd demotest
[root@platform demotest]# echo "hello liumiaocn" >demotest.txt
[root@platform demotest]# git add demotest.txt 
[root@platform demotest]# git commit -m "init"
[master (root-commit) d7a4826] init
 1 file changed, 1 insertion(+)
 create mode 100644 demotest.txt
[root@platform demotest]# git remote -v
origin  http://192.168.163.118:32001/root/demotest.git (fetch)
origin  http://192.168.163.118:32001/root/demotest.git (push)
[root@platform demotest]# 
[root@platform demotest]# git push origin master
Username for 'http://192.168.163.118:32001': ^C
[root@platform demotest]# 

直接修改.git/config文件即可,其实这种方式和git clone中明示用户名密码基本一致。config文件有三层,详细可参看:https://blog.csdn.net/liumiaocn/article/details/81068478
修改前

[root@platform demotest]# cd .git
[root@platform .git]# ls
COMMIT_EDITMSG  HEAD  branches  config  description  hooks  index  info  logs  objects  refs
[root@platform .git]# cat config
[core]
    repositoryformatversion = 0
    filemode = true
    bare = false
    logallrefupdates = true
[remote "origin"]
    url = http://192.168.163.118:32001/root/demotest.git
    fetch = +refs/heads/*:refs/remotes/origin/*
[branch "master"]
    remote = origin
    merge = refs/heads/master
[root@platform .git]#

修改后

[root@platform .git]# cat config
[core]
    repositoryformatversion = 0
    filemode = true
    bare = false
    logallrefupdates = true
[remote "origin"]
    url = http://root:12345678@192.168.163.118:32001/root/demotest.git
    fetch = +refs/heads/*:refs/remotes/origin/*
[branch "master"]
    remote = origin
    merge = refs/heads/master
[root@platform .git]#

再次执行git push

[root@platform demotest]# pwd
/root/demotest
[root@platform demotest]# ls
demotest.txt
[root@platform demotest]# git push origin master
Counting objects: 3, done.
Writing objects: 100% (3/3), 228 bytes | 0 bytes/s, done.
Total 3 (delta 0), reused 0 (delta 0)
To http://root:12345678@192.168.163.118:32001/root/demotest.git
 * [new branch]      master -> master
[root@platform demotest]# 

方式5: 在remote中加入用户名/密码

使用场景:
通过对git的remote进行设定使其包含用户名/密码来实现git push等操作时无需再次输入用户名密码

输入用户名/密码clone仓库

[root@platform ~]# git clone "http://192.168.163.118:32001/root/demotest.git"
Cloning into 'demotest'...
Username for 'http://192.168.163.118:32001': root
Password for 'http://[email protected]:32001': 
remote: Counting objects: 3, done.
remote: Total 3 (delta 0), reused 0 (delta 0)
Unpacking objects: 100% (3/3), done.
[root@platform ~]#

修改remote

[root@platform ~]# cd demotest/
[root@platform demotest]# git remote -v
origin  http://192.168.163.118:32001/root/demotest.git (fetch)
origin  http://192.168.163.118:32001/root/demotest.git (push)
[root@platform demotest]# git remote set-url origin http://root:[email protected]:32001/root/demotest.git
[root@platform demotest]# git remote -v
origin  http://root:12345678@192.168.163.118:32001/root/demotest.git (fetch)
origin  http://root:12345678@192.168.163.118:32001/root/demotest.git (push)
[root@platform demotest]#

实际修改的内容,最终还是落到了项目级别的config文件上

[root@platform demotest]# cd .git
[root@platform .git]# ls
HEAD  branches  config  description  hooks  index  info  logs  objects  packed-refs  refs
[root@platform .git]# cat config
[core]
    repositoryformatversion = 0
    filemode = true
    bare = false
    logallrefupdates = true
[remote "origin"]
    url = http://root:12345678@192.168.163.118:32001/root/demotest.git
    fetch = +refs/heads/*:refs/remotes/origin/*
[branch "master"]
    remote = origin
    merge = refs/heads/master
[root@platform .git]#

添加一个文件,然后push

[root@platform .git]# cd ..
[root@platform demotest]# touch hellotest
[root@platform demotest]# git add hellotest 
[root@platform demotest]# git commit -m "add hellotest"
[master 9c80bdd] add hellotest
 1 file changed, 0 insertions(+), 0 deletions(-)
 create mode 100644 hellotest
[root@platform demotest]# git push origin master
Counting objects: 4, done.
Compressing objects: 100% (2/2), done.
Writing objects: 100% (3/3), 276 bytes | 0 bytes/s, done.
Total 3 (delta 0), reused 0 (delta 0)
To http://root:12345678@192.168.163.118:32001/root/demotest.git
   d7a4826..9c80bdd  master -> master
[root@platform demotest]#

你可能感兴趣的:(工具,DevOps,DevOps系列之:版本管理)