git - 获取特定文件/文件夹的所有先前版本 [英] git - getting ALL previous version of a specific file/folder

查看:531
本文介绍了git - 获取特定文件/文件夹的所有先前版本的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想在git仓库中检索所有以前版本的特定文件。



我发现可以得到一个特定的文件版本与结帐命令,但我希望他们都。而使用深度选项的git clone命令似乎不允许我克隆子文件夹(无效的存储库名称)。



你知道这是否可行如何?



谢谢

解决方案

strong> all 版本,但答案不会传递。特别是如果该文件有数百个修订版(所有建议都过于手动)。唯一的半工作解决方案是由@Tobias在注释中提出的,但是建议bash循环会以随机顺序构建文件,以及在对我们的回购使用时会产生数百个空文件。其中一个原因是rev-list - all --objects会列出不同的对象(包括树木 - 但对我们的目的没用)。

Tobias的解决方案,增加了计数器,清理了一下,最终以下面列出的bash脚本的形式重新发明了轮子。



脚本会:

- 将所有文件版本解压到/ tmp / all_versions_exported

- 取1个参数 - git仓库中文件的相对路径

- 给出结果文件名numeric前缀(可排序)

- 在结果文件中提及已检查的文件名(告诉苹果与橘子不同)

- 在结果文件中提及提交日期(请参见下面的输出示例) >
- 不会创建空的结果文件



cat / usr / local / bin / git_export_all_file_versions

 #!/ bin / bash 

#我们将把文件的所有git版本写入这个文件夹:
EXPORT_TO = / tmp / all_versions_exported

#取文件的相对路径来检查
GIT_PATH_TO_FILE = $ 1

#----------------不要在这行下面编辑 - ------------

USAGE =请cd到你的git proj的根目录并指定路径来提交给你检查(例如:$ 0 some / path / to / file)

#检查是否有参数
if [$ {GIT_PATH_TO_FILE}==];然后
echoerror:no arguments given。$ {USAGE}>& 2
exit 1
fi

#检查文件是否存在
如果[! -f $ {GIT_PATH_TO_FILE}];然后
echoerror:File'$ {GIT_PATH_TO_FILE}'does not exist。$ {USAGE}>& 2
exit 1
fi

#从给定的相对路径中提取一个文件名(将在结果文件名中使用)
GIT_SHORT_FILENAME = $(basename $ GIT_PATH_TO_FILE)

创建文件夹以存储文件的所有修订
如果[! -d $ {EXPORT_TO}];然后
回显创建文件夹:$ {EXPORT_TO}
mkdir $ {EXPORT_TO}
fi

##取消注释下一行以在每次运行时清除导出文件夹脚本
#rm $ {EXPORT_TO} / *

#重置coutner
COUNT = 0

#迭代所有修订
git rev- list --all --objects - $ {GIT_PATH_TO_FILE} | \
cut -d''-f1 | \
读h;做\
COUNT = $((COUNT + 1)); \
COUNT_PRETTY = $(printf%04d$ COUNT); \
COMMIT_DATE =`git show $ h |头-3 | grep'Date:'| awk'{print $ 4' - '$ 3' - '$ 6}'`; \
if [$ {COMMIT_DATE}!=];那么\
git cat-file -p $ {h}:$ {GIT_PATH_TO_FILE}> $ {EXPORT_TO} / $ {COUNT_PRETTY}。$ {COMMIT_DATE}。$ {h}。$ {GIT_SHORT_FILENAME}; \
fi; \
完成

#return成功代码
echoresult stored to $ {EXPORT_TO}
exit 0



用法示例:

  cd / home / myname / my-git-repo 

git_export_all_file_versions docs / howto / readme.txt
结果存储到/ tmp / all_versions_exported

ls / tmp / all_versions_exported
0001.17-Oct-2016.ee0a1880ab815fd8f67bc4299780fc0b34f27b30 .readme.txt
0002.3-OCT-2016.d305158b94bedabb758ff1bb5e1ad74ed7ccd2c3.readme.txt
0003.29九月2016.7414a3de62529bfdd3cb1dd20ebc1a977793102f.readme.txt
0004.28九月2016.604cc0a34ec689606f7d3b2b5bbced1eece7483d.readme.txt
0005.28-Sep-2016.198043c219c81d776c6d8a20e4f36bd6d8a57825.readme.txt
0006.9-Sep-2016.5aea5191d4b86aec416b031cb84c2b78603a8b0f.readme.txt
<依此类推。 。 >

编辑:如果您看到类似这样的错误:


fatal:不是有效的对象名称
3e93eba38b31b8b81905ceaa95eb47bbaed46494:readme.txt



<这意味着你已经从你的git项目的根文件夹中启动了脚本。


I want to retrieve all previous version of a specific file in a git repository.

I see it is possible to get one specific version with the checkout command, but I want them all. And the git clone command with the depth option doesn't seem to allow me to clone subfolder ("not valid repository name").

Do you know if it is possible and how?

Thank you

解决方案

OP wanted to retrieve all versions, but the answers would not deliver. Especially if the file has hundreds of revisions (all suggestions are too manual). The only half-working solution was proposed by @Tobias in the comments, but suggested bash loop would build files in random order as well as it generates hundreds of empty files when used against our repos. One of the reasons was that "rev-list --all --objects" would list different objects (trees included - but useless for our purpose).

I started with Tobias's solution, added counters, clean up a bit and end up reinventing the wheel in form of the bash script listed below.

The script would:
- extract all file versions to /tmp/all_versions_exported
- take 1 argument - relative path to the file inside git repo
- give result filenames numeric prefix (sortable)
- mention inspected filename in result files (to tell apples apart from oranges:)
- mention commit date in the result filename (see output example below)
- not create empty result files

cat /usr/local/bin/git_export_all_file_versions

#!/bin/bash

# we'll write all git versions of the file to this folder:
EXPORT_TO=/tmp/all_versions_exported

# take relative path to the file to inspect
GIT_PATH_TO_FILE=$1

# ---------------- don't edit below this line --------------

USAGE="Please cd to the root of your git proj and specify path to file you with to inspect (example: $0 some/path/to/file)"

# check if got argument
if [ "${GIT_PATH_TO_FILE}" == "" ]; then
    echo "error: no arguments given. ${USAGE}" >&2
    exit 1
fi

# check if file exist
if [ ! -f ${GIT_PATH_TO_FILE} ]; then
    echo "error: File '${GIT_PATH_TO_FILE}' does not exist. ${USAGE}" >&2
    exit 1
fi

# extract just a filename from given relative path (will be used in result file names)
GIT_SHORT_FILENAME=$(basename $GIT_PATH_TO_FILE)

# create folder to store all revisions of the file
if [ ! -d ${EXPORT_TO} ]; then
    echo "creating folder: ${EXPORT_TO}"
    mkdir ${EXPORT_TO}
fi

## uncomment next line to clear export folder each time you run script
#rm ${EXPORT_TO}/*

# reset coutner
COUNT=0

# iterate all revisions
git rev-list --all --objects -- ${GIT_PATH_TO_FILE} | \
    cut -d ' ' -f1 | \
while read h; do \
     COUNT=$((COUNT + 1)); \
     COUNT_PRETTY=$(printf "%04d" $COUNT); \
     COMMIT_DATE=`git show $h | head -3 | grep 'Date:' | awk '{print $4"-"$3"-"$6}'`; \
     if [ "${COMMIT_DATE}" != "" ]; then \
         git cat-file -p ${h}:${GIT_PATH_TO_FILE} > ${EXPORT_TO}/${COUNT_PRETTY}.${COMMIT_DATE}.${h}.${GIT_SHORT_FILENAME};\
     fi;\
done    

# return success code
echo "result stored to ${EXPORT_TO}"
exit 0


Usage example:

cd /home/myname/my-git-repo

git_export_all_file_versions docs/howto/readme.txt
    result stored to /tmp/all_versions_exported

ls /tmp/all_versions_exported
    0001.17-Oct-2016.ee0a1880ab815fd8f67bc4299780fc0b34f27b30.readme.txt
    0002.3-Oct-2016.d305158b94bedabb758ff1bb5e1ad74ed7ccd2c3.readme.txt
    0003.29-Sep-2016.7414a3de62529bfdd3cb1dd20ebc1a977793102f.readme.txt
    0004.28-Sep-2016.604cc0a34ec689606f7d3b2b5bbced1eece7483d.readme.txt
    0005.28-Sep-2016.198043c219c81d776c6d8a20e4f36bd6d8a57825.readme.txt
    0006.9-Sep-2016.5aea5191d4b86aec416b031cb84c2b78603a8b0f.readme.txt
    <and so on and on . . .>

edit: if you see errors like this:

fatal: Not a valid object name 3e93eba38b31b8b81905ceaa95eb47bbaed46494:readme.txt

it means you've started the script not from the root folder of your git project.

这篇关于git - 获取特定文件/文件夹的所有先前版本的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆