Git服务器上怎么获取push上来的代码

在git服务器上,通常无法直接获得客户端push上来的代码。客户端push上来的代码会被压缩之后存放到objects/目录下,而不是直接存储为文件的形式。那么,有没有方法可以获得push上来的代码呢?当然有,只需要这 3 3 3 个命令:

git ls-tree
git diff-tree
git show

下面来依次讲解这 3 3 3 个命令。

准备工作

为了方便,我将git服务器和客户端都存放在本地。

新建两个文件夹clientserver,表示git客户端和服务器。

mkdir client
mkdir server

创建客户端仓库,并设置origin地址:

cd client
git init
git remote add origin ../server

创建服务器裸仓库

cd server
git init --bare

git ls-tree

该命令用于列出某一次提交的所有文件。
用法:

$ git ls-tree
用法:git ls-tree [<选项>] <树对象> [<路径>...]

    -d                    只显示树
    -r                    递归到子树
    -t                    当递归时显示树
    -z                    条目以 NUL 字符终止
    -l, --long            包括对象大小
    --name-only           只列出文件名
    --name-status         只列出文件名
    --full-name           使用文件的全路径
    --full-tree           列出整个树;不仅仅当前目录(隐含 --full-name)
    --abbrev[=<n>]<n> 位数字显示 SHA-1 哈希值

即:

git ls-tree [<选项>] <提交ID>

示例:

在客户端上创建若干个文件

cd client
touch 1
echo "114514" > 2
mkdir d
touch d/3
echo "1919810" > d/4

然后提交、push:

git add .
git commit -m "1145141919810"
git push origin master

再切换到服务器目录执行ls-tree

cd ../server
git ls-tree HEAD

这将显示最新一次提交(HEAD)的文件列表。

输出结果如下:

$ git ls-tree HEAD
100644 blob e69de29bb2d1d6434b8b29ae775ad8c2e48c5391	1
100644 blob fbb8c85a6e13028d79c94a902fb90118d9b3b75e	2
040000 tree b800fad10873594aa94418355acf20265a2548ad	d

注意到这条命令显示了文件的权限、类型、哈希值、和文件名。

诶,为什么这条命令只显示了文件夹d,没显示d/3d/4啊?

使用ls-tree -r可以递归显示。

$ git ls-tree -r HEAD
100644 blob e69de29bb2d1d6434b8b29ae775ad8c2e48c5391	1
100644 blob fbb8c85a6e13028d79c94a902fb90118d9b3b75e	2
100644 blob e69de29bb2d1d6434b8b29ae775ad8c2e48c5391	d/3
100644 blob 66b577f30658867f61b1c93fb9cd604618553e4f	d/4

我只想要文件名怎么办?当然可以ls-tree -r HEAD | awk '{print $4}',但是有更简单的方法。

$ git ls-tree -r --name-only HEAD
1
2
d/3
d/4

--name-only可以只显示文件名。

git diff-tree

只显示变化的文件,和ls-tree用法很像。可以通过执行git diff-tree(不加参数)或者git help diff-tree查看帮助。

示例:

切换回client目录,删掉文件1,创建文件d/5

cd ../client
rm 1
touch d/5
git add .
git commit -m 1
git push origin master

然后在server目录执行git diff-tree -r HEAD

cd ../server
git diff-tree -r HEAD

结果:

$ git diff-tree -r HEAD
af992cc27b020f86c8cba0822a81418c524216ad
:100644 000000 e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 0000000000000000000000000000000000000000 D	1
:000000 100644 0000000000000000000000000000000000000000 e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 A	d/5

显然,这条命令显示了变化的文件列表,原来的权限、哈希值,现在的权限、哈希值,以及变化的状态。

git show

用法:

不加任何参数,可以查看提交日志。

$ git show
commit af992cc27b020f86c8cba0822a81418c524216ad (HEAD -> master)
Author: wchengk09 <wchengk09@163.com>
Date:   Thu Aug 10 09:58:12 2023 +0800

    1

diff --git a/1 b/d/5
similarity index 100%
rename from 1
rename to d/5

git show <提交ID>:<文件>,查看某一次提交的文件内容。

$ git show HEAD:d/4
1919810

注意到上面的命令显示了最新一次提交当中d/4的内容。

正题:如何获取客户端push上来的文件

显然,有两种方法:

  1. 执行git ls-tree,获取到文件列表后,再依次git show
  2. 执行git diff-tree,获取到变化的文件列表后,再依次处理变化的文件。

本文以第一种方法为例,写一个脚本。它会将push上来的代码存放到src目录下。

#!/bin/bash

cd /path/to/your/server/repository
mkdir -p src

# 先清理目录(以防git push删除了某些文件)
rm -rf src/*

# 遍历文件列表
for i in $(git ls-tree --name-only -r HEAD); do
    # 保证文件所在的目录存在
    (echo $i | grep / > /dev/null) && mkdir -p src/$(echo $i | rev | cut -d "/" -f 2- | rev)
    # 显示文件
    git show HEAD:$i > src/$i
done

代码中的(echo $i | grep / > /dev/null) && mkdir -p src/$(echo $i | rev | cut -d "/" -f 2- | rev)什么意思呢?就是说,如果文件$i的文件名包含/,说明$i在一个目录下,直接git show重定向到对应目录会报No such file or directory,所以需要mkdir -p创建目录。$(echo $i | rev | cut -d "/" -f 2- | rev)表示$i所在的目录 (如果$ipath/to/xxx,则$(echo $i | rev | cut -d "/" -f 2- | rev)path/to

如何在客户端push时自动运行这个脚本?

可以设置git hooks

git hooks可以在客户端执行某些操作时自动执行脚本。

其中post-receive脚本是客户端push完成之后执行的脚本。

我们只需要将刚才的脚本移动到server目录下的hooks子目录中,然后重命名为post-receive,最后添加可执行权限即可:

cd server/hooks
cp <刚才那个脚本的路径> ./post-receive
chmod +x post-receive

这样,客户端push的时候,所有的代码都会导出至src目录下。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值