Вопрос

Мне было интересно, существует ли хорошее решение "git export", которое создает копию дерева без .git каталог репозитория.Есть по крайней мере три метода, о которых я знаю:

  1. git clone с последующим удалением .git каталог репозитория.
  2. git checkout-index ссылается на эту функциональность, но начинается с "Просто прочитайте нужное дерево в индекс ...", что я не совсем уверен, как это сделать.
  3. git-export это сторонний скрипт, который, по сути, выполняет git clone во временное местоположение, за которым следует rsync --exclude='.git' в конечный пункт назначения.

Ни одно из этих решений на самом деле не кажется мне удовлетворительным.Самый близкий к svn export может быть вариант 1, потому что оба они требуют, чтобы целевой каталог сначала был пустым.Но вариант 2 кажется еще лучше, если предположить, что я смогу понять, что значит считывать дерево в индекс.

Это было полезно?

Решение

Вероятно, самый простой способ достичь этого - с помощью git archive.Если вам действительно нужно только развернутое дерево, вы можете сделать что-то вроде этого.

git archive master | tar -x -C /somewhere/else

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

git archive master | bzip2 >source-tree.tar.bz2

ZIP - архив:

git archive --format zip --output /full/path/to/zipfile.zip master 

git help archive для получения более подробной информации, он довольно гибкий.


Имейте в виду, что даже если архив не будет содержать каталог .git, он, однако, будет содержать другие скрытые файлы, специфичные для git, такие как .gitignore, .gitattributes и т.д.Если вы не хотите, чтобы они были в архиве, убедитесь, что вы используете атрибут export-ignore в файле .gitattributes, и зафиксируйте это перед созданием архива. Подробнее...


Примечание:Если вы заинтересованы в экспорте индекса, то команда

git checkout-index -a -f --prefix=/destination/path/

(См . Ответ Грега для получения более подробной информации)

Другие советы

Я выяснил, что означает вариант 2.Из репозитория вы можете сделать:

git checkout-index -a -f --prefix=/destination/path/

Косая черта в конце пути важна, иначе это приведет к тому, что файлы будут находиться в /destination с префиксом 'path'.

Поскольку в обычной ситуации индекс содержит содержимое репозитория, нет ничего особенного, что нужно сделать, чтобы "прочитать нужное дерево в индекс".Это уже есть.

Тот Самый -a флаг необходим для проверки всех файлов в индексе (я не уверен, что значит опустить этот флаг в данной ситуации, поскольку он не делает того, что я хочу).Тот Самый -f флаг принудительно перезаписывает все существующие файлы в выходных данных, чего эта команда обычно не делает.

Похоже, это тот самый "git export", который я искал.

git archive также работает с удаленным репозиторием.

git archive --format=tar \
--remote=ssh://remote_server/remote_repository master | tar -xf -

Чтобы экспортировать определенный путь внутри репозитория, добавьте столько путей, сколько пожелаете, в качестве последнего аргумента в git, например:

git archive --format=tar \
--remote=ssh://remote_server/remote_repository master path1/ path2/ | tar -xv

enter image description here

Особый случай ответа, если репозиторий размещен на GitHub.

Просто используй svn export.

Насколько я знаю, Github не позволяет archive --remote.Хотя GitHub является совместимость с svn и у них действительно есть все репозитории git svn доступный, чтобы вы могли просто использовать svn export как и обычно, с некоторыми изменениями в вашем URL-адресе GitHub.

Например, чтобы экспортировать весь репозиторий целиком, обратите внимание, как trunk в URL-адресе заменяет master (или что бы там ни было головная ветвь проекта установлена на):

svn export https://github.com/username/repo-name/trunk/

И вы можете экспортировать один файл или даже определенный путь или папку:

svn export https://github.com/username/repo-name/trunk/src/lib/folder

Пример с Библиотека JavaScript jQuery

Тот Самый HEAD филиал или мастер филиал будет доступен с помощью trunk:

svn ls https://github.com/jquery/jquery/trunk

Тот , кто не-HEAD ветви будет доступен в разделе /branches/:

svn ls https://github.com/jquery/jquery/branches/2.1-stable

Все Теги под /tags/ таким же образом:

svn ls https://github.com/jquery/jquery/tags/2.1.3

Из самого Руководство по Git:

Использование git-checkout-index для "экспорта всего дерева"

Возможность использования префикса в основном делает тривиальным использование git-checkout-index в качестве функции "экспорта в виде дерева".Просто внесите нужное дерево в индекс и выполните:

$ git checkout-index --prefix=git-export-dir/ -a

Я написал простую оболочку вокруг git-checkout-index который вы можете использовать следующим образом:

git export ~/the/destination/dir

Если целевой каталог уже существует, вам нужно будет добавить -f или --force.

Установка проста;просто поместите сценарий куда-нибудь в свой PATH, и убедитесь, что это исполняемый файл.

Репозиторий github для git-export

Похоже, что это меньшая проблема с Git, чем с SVN.Git помещает папку .git только в корневой каталог репозитория, тогда как SVN помещает папку .svn в каждый подкаталог.Таким образом, "svn export" позволяет избежать рекурсивной магии командной строки, тогда как в Git рекурсия не требуется.

Эквивалент

svn export . otherpath

внутри существующего репозитория находится

git archive branchname | (cd otherpath; tar x)

Эквивалент

svn export url otherpath

является

git archive --remote=url branchname | (cd otherpath; tar x)

Если вы не исключаете файлы с помощью .gitattributes export-ignore тогда попробуй git checkout

mkdir /path/to/checkout/
git --git-dir=/path/to/repo/.git --work-tree=/path/to/checkout/ checkout -f -q

-f
При выезде пути из индекса, не разрушаются при удалении записи;вместо этого несвязанные записи игнорируются.

и

-q
Избегайте многословия

Кроме того, вы можете получить любую ветку или тег или из определенной ревизии фиксации, как в SVN, просто добавив SHA1 (SHA1 в Git эквивалентен номеру редакции в SVN)

mkdir /path/to/checkout/
git --git-dir=/path/to/repo/.git --work-tree=/path/to/checkout/ checkout 2ef2e1f2de5f3d4f5e87df7d8 -f -q -- ./

Тот Самый /path/to/checkout/ должно быть пустым, Git не удалит ни одного файла, но перезапишет файлы с тем же именем без какого-либо предупреждения

Обновить:Чтобы избежать проблемы с отключением или оставить нетронутым рабочий репозиторий при использовании checkout для экспорта с тегами, ветвями или SHA1, вам необходимо добавить -- ./ в конце

Двойное тире -- сообщает git, что все, что находится после тире, является путями или файлами, а также в этом случае сообщает git checkout чтобы не менять HEAD

Примеры:

Эта команда получит только каталог libs, а также readme.txt файл из этого именно коммита

git --git-dir=/path/to/repo/.git --work-tree=/path/to/checkout/ checkout fef2e1f2de5f3d4f5e87df7d8 -f -q -- ./libs ./docs/readme.txt

Это создаст (перезапишет) my_file_2_behind_HEAD.txt два фиксации за головой HEAD^2

git --git-dir=/path/to/repo/.git --work-tree=/path/to/checkout/ checkout HEAD^2 -f -q -- ./my_file_2_behind_HEAD.txt

Чтобы получить экспорт другой ветки

git --git-dir=/path/to/repo/.git --work-tree=/path/to/checkout/ checkout myotherbranch -f -q -- ./

Обратите внимание на это ./ находится относительно корня репозитория

Я широко использую git-подмодули.Это работает у меня:

rsync -a ./FROM/ ./TO --exclude='.*'

Я часто заходил на эту страницу, когда искал способ экспортировать репозиторий git.В моем ответе на этот вопрос рассматриваются три свойства, которыми svn export обладает по своей конструкции по сравнению с git, поскольку svn придерживается подхода централизованного репозитория:

  • Это сводит к минимуму трафик в удаленный репозиторий, поскольку не экспортирует все версии
  • Он не включает метаинформацию в каталог экспорта
  • Экспорт определенной ветви с помощью svn осуществляется путем указания соответствующего пути

    git clone --depth 1 --branch master git://git.somewhere destination_path
    rm -rf destination_path/.git
    

При сборке определенного релиза полезно клонировать стабильную ветку, как, например, --branch stable или --branch release/0.9.

При этом будет скопировано все содержимое, за вычетом файлов .dot.Я использую это для экспорта git-клонированных проектов в git-репозиторий моего веб-приложения без содержимого .git.

cp -R ./путь к git-репозиторию /путь/к/месту назначения/

Обычный старый bash работает просто великолепно :)

Так же просто, как клонировать, а затем удалить папку .git:

git clone url_of_your_repo path_to_export && rm -rf path_to_export/.git

ДА, это это чистая и аккуратная команда для архивирования вашего кода без какого-либо включения git в архив, и ее удобно передавать, не беспокоясь о какой-либо истории коммитов git.

git archive --format zip --output /full/path/to/zipfile.zip master 

Я просто хочу отметить, что в том случае, если вы

  1. экспорт вложенной папки репозитория (именно так я использовал функцию экспорта SVN)
  2. вы согласны с копированием всего из этой папки в пункт назначения развертывания
  3. и поскольку у вас уже есть копия всего репозитория на месте.

Тогда вы можете просто использовать cp foo [destination] вместо упомянутого git-archive master foo | -x -C [destination].

Для пользователей GitHub git archive --remote метод не будет работать напрямую, так как URL-адрес экспорта является эфемерным.Вы должны запросить URL-адрес у GitHub, а затем загрузить этот URL. curl это упрощает задачу:

curl -L https://api.github.com/repos/VENDOR/PROJECT/tarball | tar xzf -

Это даст вам экспортированный код в локальном каталоге.Пример:

$ curl -L https://api.github.com/repos/jpic/bashworks/tarball | tar xzf -
$ ls jpic-bashworks-34f4441/
break  conf  docs  hack  LICENSE  mlog  module  mpd  mtests  os  README.rst  remote  todo  vcs  vps  wepcrack

Редактировать
Если вы хотите, чтобы код был помещен в определенный, существующий каталог (а не случайный из github):

curl -L https://api.github.com/repos/VENDOR/PROJECT/tarball | \
tar xzC /path/you/want --strip 1

Вы можете заархивировать удаленное репозиторий при любой фиксации в виде zip-файла.

git archive --format=zip --output=archive.zip --remote=USERNAME@HOSTNAME:PROJECTNAME.git HASHOFGITCOMMIT

Bash-реализация git-экспорта.

Я разделил процессы создания и удаления файлов .empty на отдельные функции с целью повторного использования их в реализации 'git-archive' (будет опубликовано позже).

Я также добавил файл '.gitattributes' в процесс, чтобы удалить ненужные файлы из целевой папки экспорта.Добавил детализацию в процесс, сделав функцию 'git-export' более эффективной.

EMPTY_FILE=".пустой";

function create_empty () {
## Processing path (target-dir):
    TRG_PATH="${1}";
## Component(s):
    EXCLUDE_DIR=".git";
echo -en "\nAdding '${EMPTY_FILE}' files to empty folder(s): ...";
    find ${TRG_PATH} -not -path "*/${EXCLUDE_DIR}/*" -type d -empty -exec touch {}/${EMPTY_FILE} \;
#echo "done.";
## Purging SRC/TRG_DIRs variable(s):
    unset TRG_PATH EMPTY_FILE EXCLUDE_DIR;
    return 0;
  }

declare -a GIT_EXCLUDE;
function load_exclude () {
    SRC_PATH="${1}";
    ITEMS=0; while read LINE; do
#      echo -e "Line [${ITEMS}]: '${LINE%%\ *}'";
      GIT_EXCLUDE[((ITEMS++))]=${LINE%%\ *};
    done < ${SRC_PATH}/.gitattributes;
    GIT_EXCLUDE[${ITEMS}]="${EMPTY_FILE}";
## Purging variable(s):
    unset SRC_PATH ITEMS;
    return 0;
  }

function purge_empty () {
## Processing path (Source/Target-dir):
    SRC_PATH="${1}";
    TRG_PATH="${2}";
echo -e "\nPurging Git-Specific component(s): ... ";
    find ${SRC_PATH} -type f -name ${EMPTY_FILE} -exec /bin/rm '{}' \;
    for xRULE in ${GIT_EXCLUDE[@]}; do
echo -en "    '${TRG_PATH}/{${xRULE}}' files ... ";
      find ${TRG_PATH} -type f -name "${xRULE}" -exec /bin/rm -rf '{}' \;
echo "done.'";
    done;
echo -e "done.\n"
## Purging SRC/TRG_PATHs variable(s):
    unset SRC_PATH; unset TRG_PATH;
    return 0;
  }

function git-export () {
    TRG_DIR="${1}"; SRC_DIR="${2}";
    if [ -z "${SRC_DIR}" ]; then SRC_DIR="${PWD}"; fi
    load_exclude "${SRC_DIR}";
## Dynamically added '.empty' files to the Git-Structure:
    create_empty "${SRC_DIR}";
    GIT_COMMIT="Including '${EMPTY_FILE}' files into Git-Index container."; #echo -e "\n${GIT_COMMIT}";
    git add .; git commit --quiet --all --verbose --message "${GIT_COMMIT}";
    if [ "${?}" -eq 0 ]; then echo " done."; fi
    /bin/rm -rf ${TRG_DIR} && mkdir -p "${TRG_DIR}";
echo -en "\nChecking-Out Index component(s): ... ";
    git checkout-index --prefix=${TRG_DIR}/ -q -f -a
## Reset: --mixed = reset HEAD and index:
    if [ "${?}" -eq 0 ]; then
echo "done."; echo -en "Resetting HEAD and Index: ... ";
        git reset --soft HEAD^;
        if [ "${?}" -eq 0 ]; then
echo "done.";
## Purging Git-specific components and '.empty' files from Target-Dir:
            purge_empty "${SRC_DIR}" "${TRG_DIR}"
          else echo "failed.";
        fi
## Archiving exported-content:
echo -en "Archiving Checked-Out component(s): ... ";
        if [ -f "${TRG_DIR}.tgz" ]; then /bin/rm ${TRG_DIR}.tgz; fi
        cd ${TRG_DIR} && tar -czf ${TRG_DIR}.tgz ./; cd ${SRC_DIR}
echo "done.";
## Listing *.tgz file attributes:
## Warning: Un-TAR this file to a specific directory:
        ls -al ${TRG_DIR}.tgz
      else echo "failed.";
    fi
## Purgin all references to Un-Staged File(s):
   git reset HEAD;
## Purging SRC/TRG_DIRs variable(s):
    unset SRC_DIR; unset TRG_DIR;
    echo "";
    return 0;
  }

Выходной сигнал:

$ git-экспорт /tmp/rel-1.0.0

Добавление файлов ".empty" в пустые папки:...Выполнено.

Извлекаемый индексный компонент (ы):...Выполнено.

Сброс ГОЛОВКИ и указателя:...Выполнено.

Очистка специфичных для Git компонентов:...

файлы '/tmp/rel-1.0.0/{.buildpath}' ...сделано.'

файлы '/tmp/rel-1.0.0/{.project}' ...сделано.'

файлы '/tmp/rel-1.0.0/{.gitignore}' ...сделано.'

файлы '/tmp/rel-1.0.0/{.git}' ...сделано.'

файлы '/tmp/rel-1.0.0/{.gitattributes}' ...сделано.'

файлы '/tmp/rel-1.0.0/{*.mno}' ...сделано.'

файлы '/tmp/rel-1.0.0/{*~}' ...сделано.'

файлы '/tmp/rel-1.0.0/{.*~}' ...сделано.'

файлы '/tmp/rel-1.0.0/{*.swp}' ...сделано.'

файлы '/tmp/rel-1.0.0/{*.swo}' ...сделано.'

файлы '/tmp/rel-1.0.0/{.DS_Store}' ...сделано.'

файлы '/tmp/rel-1.0.0/{.settings}' ...сделано.'

файлы '/tmp/rel-1.0.0/{.empty}' ...сделано.'

Выполнено.

Архивирование извлеченных компонентов:...Выполнено.

-rw-r--r-- 1 колесо администратора 25445901 3 ноября 12:57 /tmp/rel-1.0.0.tgz

Теперь я объединил функциональность 'git archive' в единый процесс, который использует функцию 'create_empty' и другие функции.

function git-archive () {
    PREFIX="${1}"; ## sudo mkdir -p ${PREFIX}
    REPO_PATH="`echo "${2}"|awk -F: '{print $1}'`";
    RELEASE="`echo "${2}"|awk -F: '{print $2}'`";
    USER_PATH="${PWD}";
echo "$PREFIX $REPO_PATH $RELEASE $USER_PATH";
## Dynamically added '.empty' files to the Git-Structure:
    cd "${REPO_PATH}"; populate_empty .; echo -en "\n";
#    git archive --prefix=git-1.4.0/ -o git-1.4.0.tar.gz v1.4.0
# e.g.: git-archive /var/www/htdocs /repos/domain.name/website:rel-1.0.0 --explode
    OUTPUT_FILE="${USER_PATH}/${RELEASE}.tar.gz";
    git archive --verbose --prefix=${PREFIX}/ -o ${OUTPUT_FILE} ${RELEASE}
    cd "${USER_PATH}";
    if [[ "${3}" =~ [--explode] ]]; then
      if [ -d "./${RELEASE}" ]; then /bin/rm -rf "./${RELEASE}"; fi
      mkdir -p ./${RELEASE}; tar -xzf "${OUTPUT_FILE}" -C ./${RELEASE}
    fi
## Purging SRC/TRG_DIRs variable(s):
    unset PREFIX REPO_PATH RELEASE USER_PATH OUTPUT_FILE;
    return 0;
  }

Если вам нужно что-то, что работает с подмодулями, возможно, стоит попробовать.

Примечание:

  • MASTER_DIR = проверка с вашими подмодулями также удалена
  • DEST_DIR = где закончится этот экспорт
  • Если у вас есть rsync, я думаю, вы смогли бы сделать то же самое с еще меньшей болью в шаре.

Допущения:

  • Вам нужно запустить это из родительского каталога MASTER_DIR (то есть с компакт-диска MASTER_DIR ..)
  • Предполагается, что DEST_DIR был создан.Это довольно легко изменить, чтобы включить создание DEST_DIR, если вы захотите

cd MASTER_DIR && tar -zcvf ../DEST_DIR/export.tar.gz --исключить='.git*' .&& cd ../DEST_DIR/ && tar xvfz export.tar.gz && rm export.tar.gz

На самом деле я предпочел бы иметь дист укажите в вашем Makefile (или другой системе сборки) целевой файл, который экспортирует распространяемый архив вашего кода (.tar.bz2, .zip, .jar или любой другой подходящий).Если вы используете GNU autotools или системы MakeMaker от Perl, я думаю, это существует для вас автоматически.Если нет, я настоятельно рекомендую добавить его.

ETA (2012-09-06):Ух ты, резкие отрицательные оценки.Я по-прежнему считаю, что лучше создавать свои дистрибутивы с помощью ваших инструментов сборки, а не инструмента управления исходным кодом.Я верю в создание артефактов с помощью инструментов сборки.В моей текущей работе наш основной продукт создан с использованием ant target.Мы находимся в процессе переключения систем управления исходным кодом, и наличие этой цели ant означает на одну проблему меньше при миграции.

Это скопирует файлы в диапазоне коммитов (от C до G) в tar-файл.Примечание:при этом будут зафиксированы только файлы.Не весь репозиторий.Слегка измененный по сравнению с Здесь

Пример Истории фиксации

A -> B -> C --> D --> E --> F --> G --> H --> Я

git diff-tree -r --no-commit-id --name-only --diff-filter=ACMRT C~..G | xargs tar -rf myTarFile.tar

страница руководства по git-diff-tree

-r --> рекурсия в поддеревья

--no-commit-id -> git diff-tree выводит строку с идентификатором фиксации, когда это применимо.Этот флаг подавлял вывод идентификатора фиксации.

--только имя -> Показывать только имена измененных файлов.

--diff-filter=ACMRT --> Выбрать только эти файлы. Полный список файлов смотрите здесь

C ..G --> Файлы в этом диапазоне коммитов

C~ --> Включить файлы из Commit C.Не только файлы с момента фиксации C.

| xargs tar -rf myTarFile --> вывод в tar

Мне это было нужно для сценария развертывания, и я не мог использовать ни один из вышеупомянутых подходов.Вместо этого я придумал другое решение:

#!/bin/sh
[ $# -eq 2 ] || echo "USAGE $0 REPOSITORY DESTINATION" && exit 1
REPOSITORY=$1
DESTINATION=$2
TMPNAME="/tmp/$(basename $REPOSITORY).$$"
git clone $REPOSITORY $TMPNAME
rm -rf $TMPNAME/.git
mkdir -p $DESTINATION
cp -r $TMPNAME/* $DESTINATION
rm -rf $TMPNAME

Делаем это простым способом, это функция для .bash_profile, она напрямую распаковывает архив в текущем местоположении, сначала настройте свой обычный [url: path].ПРИМЕЧАНИЕ:С помощью этой функции вы избегаете операции клонирования, она поступает непосредственно из удаленного репозитория.

gitss() {
    URL=[url:path]

    TMPFILE="`/bin/tempfile`"
    if [ "$1" = "" ]; then
        echo -e "Use: gitss repo [tree/commit]\n"
        return
    fi
    if [ "$2" = "" ]; then
        TREEISH="HEAD"
    else
        TREEISH="$2"
    fi
    echo "Getting $1/$TREEISH..."
    git archive --format=zip --remote=$URL/$1 $TREEISH > $TMPFILE && unzip $TMPFILE && echo -e "\nDone\n"
    rm $TMPFILE
}

Псевдоним для .gitconfig, требуется та же конфигурация (ПОЗАБОТЬТЕСЬ о выполнении команды внутри проектов .git, она ВСЕГДА переходит к базовому каталогу ранее как сказано здесь, пока это не будет исправлено, я лично предпочитаю функцию

ss = !env GIT_TMPFILE="`/bin/tempfile`" sh -c 'git archive --format=zip --remote=[url:path]/$1 $2 \ > $GIT_TMPFILE && unzip $GIT_TMPFILE && rm $GIT_TMPFILE' -

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

Это можно сделать следующим образом:

git clone -b someBranch --depth 1 --single-branch git://somewhere.com/repo.git \
&& rm -rf repo/.git/
  • --single-branch доступно с версии Git 1.7.10 (апрель 2012).
  • --depth есть (был?) по имеющимся сведениям неисправен, но в случае экспорта упомянутые проблемы не должны иметь значения.

Я думаю , что @Aredridelэтот пост был самым близким, но к нему есть еще кое-что - поэтому я добавлю это здесь;дело в том, что в svn, если вы находитесь во вложенной папке репозитория, и вы делаете:

/media/disk/repo_svn/subdir$ svn export . /media/disk2/repo_svn_B/subdir

тогда svn экспортирует все файлы, находящиеся под контролем версий (они также могли быть добавлены недавно;или Измененный статус) - и если у вас есть другой "мусор" в этом каталоге (и я не считаю .svn вложенные папки здесь, но видны такие вещи, как .o файлы), это будет нет быть экспортированным;будут экспортированы только те файлы, которые зарегистрированы в репозитории SVN.Для меня приятной вещью является то, что этот экспорт также включает файлы с локальными изменениями, которые имеют нет уже совершен;и еще одна приятная вещь заключается в том, что временные метки экспортированных файлов совпадают с исходными.Или, как svn help export помещает это:

  1. Экспортирует чистое дерево каталогов из рабочей копии, указанной с помощью ПУТИ 1, в редакции REV, если она задана, в противном случае при РАБОТЕ, в ПУТЬ 2....Если REV не указан, все локальные изменения будут сохранены.Файлы, не находящиеся под контролем версий не будут скопированы.

Осознать это git не сохранит временные метки, сравните выходные данные этих команд (во вложенной папке git репо по вашему выбору):

/media/disk/git_svn/subdir$ ls -la .

...и:

/media/disk/git_svn/subdir$ git archive --format=tar --prefix=junk/ HEAD | (tar -t -v --full-time -f -)

...и я, во всяком случае, замечаю, что git archive приводит к тому, что все временные метки заархивированного файла совпадают! git help archive говорит:

git archive ведет себя по-разному, когда ему присваивается идентификатор дерева, по сравнению с тем, когда ему присваивается идентификатор фиксации или идентификатор тега.В первом случае текущее время используется, как время модификации всех файлов в архиве.В последнем случае вместо этого используется время фиксации, записанное в указанном объекте фиксации.

...но, по-видимому, в обоих случаях устанавливается "время модификации каждый файл";тем самым нет сохранение фактических временных меток этих файлов!

Итак, чтобы также сохранить временные метки, вот bash скрипт, который на самом деле является "однострочным", хотя и несколько сложным - поэтому ниже он размещен в несколько строк:

/media/disk/git_svn/subdir$ git archive --format=tar master | (tar tf -) | (\
  DEST="/media/diskC/tmp/subdirB"; \
  CWD="$PWD"; \
  while read line; do \
    DN=$(dirname "$line"); BN=$(basename "$line"); \
    SRD="$CWD"; TGD="$DEST"; \
    if [ "$DN" != "." ]; then \
      SRD="$SRD/$DN" ; TGD="$TGD/$DN" ; \
      if [ ! -d "$TGD" ] ; then \
        CMD="mkdir \"$TGD\"; touch -r \"$SRD\" \"$TGD\""; \
        echo "$CMD"; \
        eval "$CMD"; \
      fi; \
    fi; \
    CMD="cp -a \"$SRD/$BN\" \"$TGD/\""; \
    echo "$CMD"; \
    eval "$CMD"; \
    done \
)

Обратите внимание, что предполагается, что вы экспортируете содержимое в "текущий" каталог (выше, /media/disk/git_svn/subdir) - и пункт назначения, в который вы экспортируете, расположен несколько неудобно, но он находится в DEST переменная среды.Обратите внимание, что с помощью этого скрипта;вы должны создать DEST создайте каталог вручную самостоятельно, прежде чем запускать приведенный выше скрипт.

После запуска скрипта вы должны иметь возможность сравнить:

ls -la /media/disk/git_svn/subdir
ls -la /media/diskC/tmp/subdirB   # DEST

...и, надеюсь, увидите те же временные метки (для тех файлов, которые находились под контролем версий).

Надеюсь, это кому-то поможет,
Ваше здоровье!

Безусловно, самый простой способ, который я видел для этого (и который также работает в Windows), - это git bundle:

git bundle create /some/bundle/path.bundle --all

Смотрите этот ответ для получения более подробной информации: Как я могу скопировать свой репозиторий git с моего компьютера с Windows на компьютер с Linux через USB-накопитель?

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

GIT_WORK_TREE=outputdirectory git checkout -f

Это особенно полезно, если вы управляете веб-сайтом с помощью репозитория git и хотели бы получить чистую версию в /var/www/.В этом случае добавьте эту команду в .git/hooks/post-receive сценарий (hooks/post-receive на голом репозитории, который больше подходит в данной ситуации)

экспорт git в zip-архив при добавлении префикса (например,имя каталога):

git archive master --prefix=directoryWithinZip/  --format=zip -o out.zip

Если вам также нужны подмодули, это должно сработать: https://github.com/meitar/git-archive-all.sh/wiki

у меня есть следующая служебная функция в моем файле .bashrc:он создает архив текущей ветви в репозитории git.

function garchive()
{
  if [[ "x$1" == "x-h" || "x$1" == "x" ]]; then
    cat <<EOF
Usage: garchive <archive-name>
create zip archive of the current branch into <archive-name>
EOF
  else
    local oname=$1
    set -x
    local bname=$(git branch | grep -F "*" | sed -e 's#^*##')
    git archive --format zip --output ${oname} ${bname}
    set +x
  fi
}
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top