Existe uma " exportação de git "(como"exportação de svn")?

tenho estado a pensar se existe uma boa solução de "exportação de git" que cria uma cópia de uma árvore sem o directório do repositório .git. Há pelo menos três métodos que conheço:

  1. git clone seguido da remoção da pasta do repositório .git.
  2. git checkout-index alude a esta funcionalidade, mas começa com "basta ler a árvore desejada no índice..."o que não sei bem como fazer.
  3. git-export é um script de terceiros que essencialmente, um git clone entra num local temporário seguido de rsync --exclude='.git' para o destino final.
Nenhuma destas soluções me parece realmente satisfatória. O mais próximo de svn export pode ser a opção 1, porque ambos requerem que o directório de destino esteja vazio primeiro. Mas a opção 2 parece ainda melhor, assumindo que consigo descobrir o que significa ler uma árvore no índice.

Author: Peter O., 2008-10-02

30 answers

A maneira mais simples de conseguir isto é com ... git archive. Se você realmente precisa apenas da árvore expandida você pode fazer algo assim.
git archive master | tar -x -C /somewhere/else

A maior parte do tempo que eu preciso para 'exportar' algo do git, eu quero um arquivo comprimido em qualquer caso para que eu faça algo assim.

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

Arquivo ZIP:

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

git help archive Para mais detalhes, é bastante flexível.


Esteja ciente de que mesmo que o arquivo não conterá o.git diretório, ele irá, No entanto, conter outros arquivos git-específicos escondidos como .gitignore,.gitatributes, etc. Se não os quiser no pacote, certifique-se que utiliza o atributo export-ignore em A.gitattributes file e commit this antes de fazer o seu arquivo. Leia mais...


Nota: Se estiver interessado em exportar o índice, o comando é

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

(ver a resposta do Greg Para mais detalhes)

 2216
Author: CB Bailey, 2018-05-29 10:10:20
Descobri o que significa a opção 2. De um repositório, você pode fazer:
git checkout-index -a -f --prefix=/destination/path/

A barra no final do caminho é importante, caso contrário, irá resultar em que os arquivos estão em /destino com um prefixo de 'caminho'.

Uma vez que numa situação normal o índice contém o conteúdo do repositório, não há nada de especial a fazer para "ler a árvore desejada no índice". Já lá está.

A bandeira -a é necessária para verificar todos os ficheiros no índice (Não tenho a certeza o que significa omitir esta bandeira nesta situação, já que não faz o que eu quero). A bandeira -f obriga a substituir quaisquer ficheiros existentes na saída, o que este comando normalmente não faz.

Este parece ser o tipo de "exportação de git" que eu procurava.
 304
Author: Greg Hewgill, 2012-05-23 15:55:15

git archive também funciona com repositório remoto.

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

Para exportar um caminho particular dentro do repo adicione todos os caminhos que desejar como último argumento ao git, por exemplo:

git archive --format=tar \
--remote=ssh://remote_server/remote_repository master path1/ path2/ | tar -xv
 242
Author: Aleksandr Somov, 2014-06-23 19:01:01

enter image description here

Uma resposta de caso especial se o repositório estiver hospedado no GitHub.

Usa apenas svn export.

Tanto quanto sei, o Github não permite. Ainda que o GitHub seja compatível com svn e eles tenham todos os repos do git svn acessíveis para que possa usar svn export como normalmente faria com alguns ajustes no seu url do GitHub.

Por exemplo, para exportar um repositório inteiro, observe como trunk no URL substitui master (ou qualquer que seja o o ramo principal do projecto está definido para):

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

E você pode exportar um único arquivo ou mesmo um determinado caminho ou pasta:

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

Exemplo com jQuery JavaScript Library

O ramo HEAD ou o ramo principal estará disponível usando trunk:

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

O não-HEAD Os ramos estarão acessíveis sob /branches/:

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

Todas as marcas sob /tags/ da mesma forma:

svn ls https://github.com/jquery/jquery/tags/2.1.3
 50
Author: Anthony Hatzopoulos, 2017-01-18 15:13:04

Do Manual do Git:

Usar o git-checkout-index para "exportar uma árvore inteira"

A capacidade do prefixo basicamente faz com que seja trivial usar o git-checkout-index como uma função de "exportação como árvore". Basta ler a árvore desejada no índice, e fazer:

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

 38
Author: jperras, 2008-10-02 02:27:07

Escrevi uma embalagem simples à volta {[1] } que podes usar assim:

git export ~/the/destination/dir

Se a pasta de destino já existir, terá de adicionar -f ou --force.

A instalação é simples; basta largar o script algures no seu PATH, e certificar-se de que é executável.

O repositório github para git-export

 37
Author: Daniel Schierbeck, 2008-10-16 17:17:00

Parece que isto é menos um problema com o Git do que com o SVN. Git só coloca um .a pasta git na raiz do repositório, enquanto o SVN coloca A.pasta svn em cada subdiretório. Então "exportação svn" evita a magia recursiva da linha de comandos, enquanto que com a recursão Git não é necessário.

 35
Author: kostmo, 2009-05-12 04:20:24

O equivalente a

svn export . otherpath

Dentro de um acordo de recompra existente está

git archive branchname | (cd otherpath; tar x)

O equivalente a

svn export url otherpath

É

git archive --remote=url branchname | (cd otherpath; tar x)
 26
Author: aredridel, 2012-02-23 15:41:55

Uso extensivamente submódulos git. Este trabalha para mim.

rsync -a ./FROM/ ./TO --exclude='.*'
 21
Author: slatvick, 2011-09-13 06:26:03

Se não estás a excluir ficheiros com .gitattributes export-ignore então tenta.git checkout

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

- f
Ao verificar os caminhos a partir do índice, não falhe depois de não se encontrar os itens; em vez disso, os itens não incorporados são ignorados.

E

- q
Evitar a verbose

Para além disso, poderá obter qualquer ramificação ou etiqueta ou de uma revisão de Commit específica, como no SVN, apenas adicionando o SHA1 (o SHA1 no Git é o equivalente ao número de revisão em SVN)

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

O /path/to/checkout/ deve estar vazio, o Git não irá apagar nenhum ficheiro, mas irá sobrepor os ficheiros com o mesmo nome sem qualquer aviso

Actualização: Para evitar o problema da decapitação ou para deixar intacto o repositório de trabalho ao usar o checkout para exportação com tags, branches ou SHA1, você precisa adicionar -- ./ no final

O dash duplo -- diz ao git que tudo depois dos traços são caminhos ou ficheiros, e também neste caso diz git checkout para não alterar o HEAD

Exemplos:

Este comando irá obter apenas o directório libs e também o ficheiro readme.txt desse commit

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

Isto irá criar (sobrepor) {[14] } dois commits por trás da cabeça 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

Para obter a exportação de outro ramo

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

Repare que {[16] } é relativo à raiz do repositório

 20
Author: user5286776117878, 2018-01-10 15:45:19

Isto vai copiar todo o conteúdo, menos o .ficheiros dot. Eu uso isso para exportar projetos clonados git para o meu aplicativo git repo sem o .tretas.

Cp-R./ path-to-git-repo /path/to/destination /

Bash simples funciona muito bem.
 16
Author: Harmon, 2010-12-10 17:17:49

Atingi esta página frequentemente ao procurar uma forma de exportar um repositório git. A minha resposta a esta pergunta considera três propriedades que a exportação de svn tem por design em comparação com o git, uma vez que o svn segue uma abordagem centralizada do repositório:

  • minimiza o tráfego para um local de repositório remoto, não exportando todas as revisões
  • não inclui meta-informação na pasta de exportação
  • Exportar um determinado ramo usando svn é realizado por especificando o caminho apropriado

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

Ao construir uma determinada versão, é útil clonar um ramo estável como por exemplo --branch stable ou --branch release/0.9.

 16
Author: Lars Schillingmann, 2012-01-22 17:31:47

Tão simples como o clone, depois apaga o .pasta git:

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

 11
Author: teleme.io, 2013-09-27 19:35:10

Só quero salientar que, no caso de seres

  1. exportar uma sub-pasta do repositório (foi assim que usei a funcionalidade de exportação do SVN)
  2. não há problema em copiar tudo desde essa pasta até ao destino de implantação
  3. e já que você já tem uma cópia de todo o repositório no lugar.

Então você pode apenas usar cp foo [destination] em vez do git-archive master foo | -x -C [destination] mencionado.

 10
Author: dkinzer, 2010-10-29 13:51:08

Para os utilizadores do GitHub, o método git archive --remote não irá funcionar directamente, dado que o URL de exportação é efémero. Você deve perguntar ao GitHub a URL, e então baixar essa URL. curl torna isso Fácil:

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

Isto dar-lhe-á o código exportado numa pasta local. Exemplo:

$ 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

Editar
Se você quiser o código colocado em um diretório específico, existente (em vez do Aleatório do github):

curl -L https://api.github.com/repos/VENDOR/PROJECT/tarball | \
tar xzC /path/you/want --strip 1
 10
Author: bishop, 2014-08-05 13:24:42

Você pode arquivar um repo remoto em qualquer ficheiro de envio como zip.

git archive --format=zip --output=archive.zip --remote=USERNAME@HOSTNAME:PROJECTNAME.git HASHOFGITCOMMIT
 9
Author: orkoden, 2012-10-09 13:49:55

Sim, Este é um comando limpo e limpo para arquivar o seu código sem qualquer inclusão do git no arquivo e é bom para passar sem se preocupar com qualquer histórico de commit do git.

git archive --format zip --output /full/path/to/zipfile.zip master 
 9
Author: zeeawan, 2017-05-23 12:26:34

Bash-implementação do git-export.

Eu segmentei o .os processos de criação e remoção de arquivos vazios em sua própria função, com o objetivo de reutilizá-los na implementação do 'Git-archive' (será postado mais tarde).

Eu também adicionei o '.o ficheiro do gitattributes para o processo, a fim de remover os ficheiros não procurados da pasta de exportação de destino. Incluiu a verbosidade no processo enquanto fazia a função' git-export ' mais eficiente.

EMPTY_FILE=".vazio";

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;
  }

Resultado:

$ git-export /tmp/rel-1.0.0

Adicionando".ficheiros ' vazios para pastas vazias: ... terminar.

Componente(s) do Índice de verificação: ... terminar.

Recolocar a cabeça e o índice:... terminar.

Purging Git-Specific component(s):...

' / tmp/rel-1, 0 / {.ficheiros ' buildpath}'... terminar.'

' / tmp/rel-1, 0 / {.ficheiros do projecto}... terminar.'

' / tmp/rel-1, 0 / {.ficheiros do gitignore... terminar.'

' / tmp/rel-1, 0 / {.ficheiros ... terminar.'

' / tmp/rel-1, 0 / {.os ficheiros GITATTRIBUTES}'... terminar.'

' / tmp/rel-1, 0 / {*.ficheiros... terminar.'

'/tmp/rel-1.0.0/ {*~}' ficheiros ... terminar.'

' / tmp/rel-1, 0 / {.*~}' arquivo ... terminar.'

' / tmp/rel-1, 0 / {*.ficheiros swp}... terminar.'

' / tmp/rel-1, 0 / {*.ficheiros swo... terminar.'

' / tmp/rel-1, 0 / {.DS_Store}" arquivo ... terminar.'

' / tmp/rel-1, 0 / {.configuração dos ficheiros'... terminar.'

' / tmp/rel-1, 0 / {.ficheiros vazios ... terminar.'

Feito.

Componente(s) de arquivamento: ... terminar.

-rw-r--r-- 1 roda de administração 25445901 3 Nov 12:57 /tmp/rel-1.0.0.TGZ

Incorporei agora a funcionalidade ' git archive 'num único processo que faz uso da função' create_empty ' e de outras funcionalidades.

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;
  }
 8
Author: tocororo, 2011-11-04 04:34:30
Se queres algo que funcione com submódulos, talvez valha a pena tentar.

Nota:

  • MASTER_DIR = uma verificação com os seus submódulos também verificados
  • DEST_DIR = onde esta exportação irá acabar
  • Se tiveres rsync, acho que serias capaz de fazer a mesma coisa com ainda menos dor de bola.

Pressupostos:

  • Você precisa de correr isto a partir da pasta-mãe do MASTER_DIR (i. e. do CD MASTER_DIR .. )
  • DEST_DIR is presumido como tendo sido criado. Isto é muito fácil de modificar para incluir a criação de um DEST_DIR se quiser

CD MASTER_DIR & & tar-zcvf ../DEST_DIR / export.alcatrao.GZ -- exclude=".git*" . && disco ../ DEST_DIR / & & tar xvfz export.alcatrao.GZ & rm export.alcatrao.gz

 8
Author: Rob Jensen, 2012-02-28 01:42:28

Isto irá copiar os ficheiros numa gama de commits (C A G) para um ficheiro tar. Nota: Isto só vai obter os arquivos commited. Não o repositório inteiro. Ligeiramente modificado a partir de aqui

Exemplo Histórico De Commit

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

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

Página de Manual do git-diff-tree

-r --> repetir em sub-árvores

--no-commit-id --> git diff-tree produz uma linha com o ID de commit quando aplicável. Esta bandeira suprimiu o resultado do ID de commit.

--name-only --> Show only names of changed files.

--diff-filter=ACMRT -- > seleccione apenas estes ficheiros. veja aqui a lista completa dos ficheiros

C..G --> ficheiros nesta gama de commits

C~ --> incluir ficheiros do Commit C. não apenas ficheiros desde o Commit C.

/ xargs tar-rf myTarFile -- > saídas para tar

 6
Author: Fuyu Persimmon, 2017-05-23 12:18:27

A minha preferência seria ter um alvo dist no seu Makefile (ou outro sistema de compilação) que exporta um arquivo distribuível do seu código (.tar.bz2, .postal, .jar, ou o que for apropriado). Se você estiver usando Autotools GNU ou os sistemas MakeMaker do Perl, eu acho que isso existe para você automaticamente. Caso contrário, recomendo vivamente a sua inclusão.

ETA (2012-09-06): Uau, más notas. Eu ainda acredito que é melhor construir suas distribuições com a sua compilação ferramentas em vez de sua ferramenta de controle de código fonte. Acredito na construção de artefactos com ferramentas. No meu trabalho atual, o nosso produto principal é construído com um alvo formiga. Estamos no meio de mudar os sistemas de controle de código fonte, e a presença deste alvo ant significa menos um aborrecimento na migração.
 5
Author: skiphoppy, 2012-09-06 13:54:17
Precisava disto para um guião de lançamento e não podia usar nenhuma das abordagens acima mencionadas. Em vez disso, descobri uma solução diferente:
#!/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
 4
Author: troelskn, 2009-07-17 10:07:43
Fazendo da maneira mais fácil, esta é uma função para .bash_ profile, abre directamente o pacote na localização actual, configura primeiro o seu [url:path] habitual. Nota: com esta função você evita a operação de clone, ela sai diretamente do repo remoto.
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
}

Alias for .gitconfig, a mesma configuração necessária (tome cuidado ao executar o comando dentro .git projects, it ALWAYS jumps to the base dir previously {[[6]} as said here , until this is fixed I personally preferred the função

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' -
 4
Author: RkG, 2010-03-19 16:32:28

Eu acho que o post de @Aredridel Estava mais próximo, mas há um pouco mais disso - então eu vou adicionar isso aqui; a coisa é, em svn, Se você está em uma subpasta de um repo, e você faz:

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

Então svn irá exportar todos os arquivos que estão sob controle de revisão (que também poderia ter recém-Adicionado; ou status Modificado) - e, se você tiver outros "lixo" no diretório (e eu não estou contando .svn subpastas aqui, mas visível coisas como .o arquivos), vai não ser exportada; somente os arquivos registrados pelo Acordo de repo SVN serão exportados. Para mim, uma coisa boa é que esta exportação também inclui arquivos com alterações locais que ainda não foram comprometidos ; e outra coisa boa é que os prazos dos arquivos exportados são os mesmos que os originais. Ou, como svn help export diz:

  1. exporta uma árvore de directórios limpa da cópia de trabalho indicada por PATH1, na revisão REV, se for indicado, caso contrário no trabalho, em PATH2. ... Se o REV não for especificado, todos os locais as mudanças serão preservadas. Os ficheiros que não estão sob controlo de versões irão não ser copiado.

Para perceber que git não irá preservar as datas, compare a saída destes comandos (numa subpasta de um git repo da sua escolha):

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

... e:

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

... e eu, em qualquer caso, reparo que git archive faz com que todos os prazos do arquivo sejam os mesmos! Diz:

Arquivo Git comporta-se de forma diferente quando é dado um ID de árvore versus quando é dado um ID de commit ou ID de marca. No primeiro caso, o a hora atual é usada como a hora de modificação de cada arquivo no arquivo. Neste último caso, o tempo de compromisso registado no objeto de commit referenciado é usado em vez disso.

... mas aparentemente ambos os casos definem o " tempo de modificação de cada arquivo"; Assim Não preservando as datas reais desses arquivos!

Assim, a fim de também preserve os tempestamps, aqui está um script bash, que na verdade é um "one-liner", embora um pouco complicado - assim abaixo é publicado em várias linhas:

/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 \
)

Note que se assume que está a exportar o conteúdo no directório "actual" (acima, /media/disk/git_svn/subdir) - e o destino para o qual está a exportar está um pouco inconveniente, mas está na variável de Ambiente DEST. Lembre-se que, com este programa, deverá criar a pasta DEST manualmente, antes de executar o programa acima do guião.

Depois do script ser executado, você deve ser capaz de comparar:

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

... e espero ver o mesmo horário (para aqueles arquivos que estavam sob controle de versão).

Espero que isto ajude alguém. Saúde!
 3
Author: sdaau, 2017-05-23 12:18:27

De longe a maneira mais fácil que eu vi para fazê-lo (e funciona também em janelas) é git bundle:

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

Veja esta resposta para mais detalhes: Como posso copiar o meu repositório de git da minha máquina do windows para uma máquina linux através de uma unidade usb?

 3
Author: B T, 2017-05-23 12:34:53

Se você precisa de submódulos também, isso deve fazer o truque: https://github.com/meitar/git-archive-all.sh/wiki

 2
Author: Brandon, 2012-08-23 15:05:20

Como eu entendo a pergunta, é mais sobre baixar apenas um determinado estado do servidor, sem história, e sem dados de outros ramos, em vez de extrair um estado de um repositório local (como muitos anwsers aqui fazem).

Isso pode ser feito assim:

git clone -b someBranch --depth 1 --single-branch git://somewhere.com/repo.git \
&& rm -rf repo/.git/
 2
Author: Ondra Žižka, 2018-03-12 14:59:27

Tenho a seguinte função de utilidade na minha.ficheiro bashrc: cria um pacote da ramificação actual num repositório 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
}
 1
Author: MichaelMoser, 2014-05-22 07:38:31

A opção 1 não parece muito eficiente. E se não houver espaço no cliente para fazer um clone e então remover a pasta .git?

Hoje dei por mim a tentar fazer isto, onde o cliente é um Pi De Framboesa com quase nenhum espaço. Além disso, eu também quero excluir alguma pasta pesada do repositório. A opção 2 e outras respostas aqui não ajudam neste cenário. Nem git archive (porque necessita de enviar um ficheiro .gitattributes, e eu não quero gravar isto exclusão no repositório). Aqui partilho a minha solução, semelhante à Opção 3, mas sem a necessidade de git clone:
tmp=`mktemp`
git ls-tree --name-only -r HEAD > $tmp
rsync -avz --files-from=$tmp --exclude='fonts/*' . raspberry:

Mudar a linha rsync para uma linha equivalente de compressão também funcionará como uma git archive mas com uma espécie de opção de exclusão (como é pedido aqui).

 1
Author: alexis, 2015-06-12 19:35:11

Eu tenho outra solução que funciona bem se você tiver uma cópia local do repositório na máquina onde você gostaria de criar a exportação. Neste caso, mova-se para esta pasta do repositório e indique este comando:

GIT_WORK_TREE=outputdirectory git checkout -f

Isto é particularmente útil se você gerenciar um site com um repositório git e gostaria de obter uma versão limpa em /var/www/. Neste caso, adicione este comando num script .git/hooks/post-receive (hooks/post-receive num repositório simples, o que é mais adequado neste situação)

 1
Author: Tom, 2018-02-23 10:30:17