Каков эквивалент времен фиксации использования для мерзавца?

Мне нужны метки времени файлов на моем локальном и на моем сервере, чтобы быть в синхронизации. Это выполняется с Подрывной деятельностью путем установки use-commit-times=true в конфигурации так, чтобы последнее, измененное каждого файла, было, когда это фиксировалось.

Каждый раз, когда я клонирую свой репозиторий, я хочу, чтобы метки времени файлов отразили, когда они были в последний раз изменены в удаленном репозитории, не, когда я клонировал repo.

Там какой-либо путь состоит в том, чтобы сделать это с мерзавцем?

92
задан Ben W 26 December 2009 в 21:53
поделиться

2 ответа

Я не уверен, что это было бы уместно для ДКС (как в "Распределенной" ДКС)

Огромная дискуссия уже состоялась в 2007 (см. эту тему)

И некоторые из ответов Линуса не были слишком увлечены этой идеей. Вот один пример:

Извините. Если вы не видите, как это WRONG, чтобы установить дату обратно к чему-то, что сделает простое "сделать" miscompile ваше дерево исходных текстов, я не знаю, какое определение "неправильно" вы говорите.
. Это РРОНГ.
Это СТУПИД.
И это абсолютно НЕВОЗМОЖНО для реализации.


(Примечание: небольшое улучшение: после проверки временные метки обновлённых файлов больше не изменяются (Git 2.2.2+, январь 2015): "git checkout - как я могу поддерживать метки времени при переключении веток?".)


Длинный ответ был:

Я думаю, что лучше просто использовать несколько репозиториев, если это что-то общее.

В общем, сообщение с метками времени не будет работать. Это просто гарантирует вам, что "make" очень плохо путается и не перекомпилирует достаточно вместо перекомпиляции слишком много .

Git делает это возможным, чтобы сделать ваш "проверить другое ответвление" вещь очень легко, многими различными способами.

Вы могли бы создать какой-нибудь тривиальный сценарий, который делает любое из следующего (от тривиального до более экзотического):

  • просто создать новое repo:

     git клонировать старое новое
    новый компакт-диск
    происхождение git-checkout/<фигура>
    

    и вот ты где. Старые временные метки хороши в вашем старом репо, и вы можете работать (и компилировать) в новом, совсем не привязываясь к старому.

    Используйте флаги "-n -l -s" для "git-клонирования", чтобы сделать это мгновенно. Для многих файлов (например, больших репозиториев, таких как ядро) это будет не так быстро, как просто переключение ветвей, но наличие второй копии рабочего дерева может быть достаточно мощным.

  • сделайте то же самое с помощью простого tar-шарика, если вы хотите

    git-архив --format=tar --prefix=new-tree/  |.
     (cd ... ; tar xvf -)
    

    , что очень быстро, если вам просто нужен снимок.

  • привыкайте к "git show", и просто смотрите на отдельные файлы.
    . Это на самом деле действительно полезно иногда. Вы просто делаете

     git показывает otherbranch:filename.
    

    в одном окне xterm, и посмотрите на тот же файл в вашей текущей ветке в другом окне. В частности, это должно быть тривиально по отношению к редакторам со скриптами (т.е. GNU emacs), где с помощью этого можно, в принципе, иметь целый "dired mode" для других ветвей внутри редактора. Насколько я знаю, режим emacs git уже предлагает нечто подобное (я не пользователь emacs)

  • , и в крайнем случае в этом "виртуальном каталоге" был хотя бы кто-то, кто работал над плагином git'а для FUSE, т.е. можно было буквально просто иметь виртуальные каталоги, показывающие все ваши ветки.

и я уверен, что любая из вышеперечисленных альтернатив лучше, чем игры с метками времени файлов.

Линус

24
ответ дан 24 November 2019 в 06:27
поделиться

Если, однако, вы действительно хотите использовать время фиксации для временных меток при извлечении, то попробуйте использовать этот скрипт и поместите его (как исполняемый) в файл $GIT_DIR/.git/hooks/post-checkout:

#!/bin/sh -e

OS=${OS:-`uname`}
old_rev="$1"
new_rev="$2"

get_file_rev() {
    git rev-list -n 1 "$new_rev" "$1"
}

if   [ "$OS" = 'Linux' ]
then
    update_file_timestamp() {
        file_time=`git show --pretty=format:%ai --abbrev-commit "$(get_file_rev "$1")" | head -n 1`
        touch -d "$file_time" "$1"
    }
elif [ "$OS" = 'FreeBSD' ]
then
    update_file_timestamp() {
        file_time=`date -r "$(git show --pretty=format:%at --abbrev-commit "$(get_file_rev "$1")" | head -n 1)" '+%Y%m%d%H%M.%S'`
        touch -h -t "$file_time" "$1"
    }
else
    echo "timestamp changing not implemented" >&2
    exit 1
fi

IFS=`printf '\t\n\t'`

git ls-files | while read -r file
do
    update_file_timestamp "$file"
done

Обратите внимание, однако, что этот скрипт вызовет довольно большую задержку при извлечении больших репозиториев (где под большим подразумевается большое количество файлов, а не большой размер файлов).

85
ответ дан 24 November 2019 в 06:27
поделиться
Другие вопросы по тегам:

Похожие вопросы: