Usando o Git em vários sistemas sem acesso à rede

84

Quero usar o controle de versão, mas, por razões de segurança, o servidor no qual estou trabalhando não tem acesso à Internet: só ​​posso mover arquivos em uma unidade flash USB. Ainda posso usar o Git com esta configuração? Posso criar pequenos patches que posso aplicar em um repositório Git?

Tutu Kaeen
fonte
65
Seu título indica que não há acesso à rede, sua pergunta diz que não há acesso à internet; uma enorme diferença.
tkausl
7
@TutuKaeen Você pode ter uma rede local que não esteja conectada à Internet. Então, em vez de github.com, você configura o servidor git, por exemplo. 192.168.1.100 e tudo o resto funciona da mesma maneira.
Agent_L 18/10/19
12
@TutuKaeen: A questão crítica é se a comunicação de rede direta (ou indireta) é possível entre as duas máquinas. Então, no seu caso, as duas máquinas estão em rede, mas as redes são separadas? Nesse caso, edite essas informações em sua pergunta.
sleske
15
@TutuKaeen Sua pergunta permanece incerta. Você diz que deseja usar o controle de versão, mas nos seus comentários você precisa que ele o implante na produção. Esses problemas nem sempre se sobrepõem. Acho que você tem boas respostas abaixo agora, mas no futuro seria útil se sua pergunta fosse mais abrangente sobre seus requisitos, o que parece ser: "Quero usar o controle de versão, minha máquina de desenvolvimento não tem acesso à Internet, ele tem acesso à rede, mas não à máquina de produção, e quero saber como obter código fora do controle de versão na máquina de produção ".
Davids
4
Parece estranho usar o termo serverpara uma máquina não conectada a nenhuma rede. Poderia ser apenas uma rede local, mesmo sem acesso à Internet, mas ainda assim é uma rede.
Patrick Gregorio

Respostas:

157

Claro, não há nada no Git que exija um protocolo específico. Imediatamente, o cliente padrão suporta HTTP (S), SSH, o protocolo Git personalizado e, principalmente, o protocolo local . Isso apenas leva o caminho para um .gitdiretório local , que pode estar dentro do diretório ativo ( /path/to/project/.git) ou apenas um diretório simples ( /path/to/project.git), embora a nomeação seja apenas uma convenção.

Isso significa que você pode, é claro, adicionar uma unidade flash como controle remoto:

git remote add origin /mnt/flashdrive/foo.git

ou, no Windows:

git remote add origin F:\foo.git

Ou adicione-o como um controle remoto adicional com um nome diferente (se você preferir originapontar para um servidor da Internet em algum lugar):

git remote add flashdrive /mnt/flashdrive/foo.git

Então você pode simplesmente pressionar / puxar para / deste controle remoto como qualquer outro.

Se você ler a documentação , notará que também existe um file://protocolo que se comporta de maneira ligeiramente diferente. É recomendável usar um caminho local, pois isso fará uso de algumas otimizações adicionais - se você usar o file://protocolo, o git usará alguns componentes de rede padrão (para conversar com o disco local), que é mais lento.

Prumo
fonte
50
Para adicionar a esta resposta excepcional - Também pode valer a pena investigar o uso de um repositório 'vazio' na unidade flash. Os repositórios 'bare' não têm uma árvore de trabalho e, portanto, eliminam uma categoria de possíveis problemas quando usados ​​como um 'ponto de autoridade' compartilhado, que soa como o caso de uso do OP.
Iron Gremlin
5
O file://também é um pouco mais flexível. Ele permite que você use alguns recursos (como clones rasos) que não podem com um caminho local.
Austin Hemmelgarn
11
@IronGremlin Você poderia expandir essa noção de "ponto de autoridade compartilhado"? Não sou especialista em Git e estou curioso sobre o que você quer dizer com isso.
Corridas do Lightness em órbita
2
@LightnessRacesinOrbit - Este é um tópico bastante denso, mas, basicamente, o git é distribuído, para que todos obtenham sua própria história. A pode pedir a B sua versão do histórico, mas C não sabe a menos que alguém lhes diga. Ter um único repositório para armazenar a história 'autoritativa' significa que D atua como uma câmara de compensação para histórias. Então, A diz a D sobre mudanças, e B e C sabem conversar com D para se manterem atualizados, em vez de fazer coisas de canal lateral entre si. Caso em questão, se o servidor do OP for C e a unidade flash for D, isso garante que o servidor não fique de fora das interações A / B.
Iron Gremlin
6
@LightnessRacesinOrbit Importante observar aqui que bare não precisa significar autoridade, é apenas útil nesse contexto. Por exemplo, também é útil porque, na falta de uma árvore em funcionamento, é um espaço menor em disco (ou largura de banda). Isso costumava ser muito mais importante do que é agora, mas ainda aparece.
Iron Gremlin
46

Em um único computador, nada de especial é necessário. Execute git initno diretório desejado e trabalhe com o Git como faria normalmente.

Para sincronizar um repositório em vários computadores, existem vários métodos.

Método 1a (sem rede): você pode criar um 'repositório vazio' no pen drive, pressioná-lo e puxá-lo como faria com qualquer outro repositório remoto. Em outras palavras, as operações do repositório por caminhos locais não diferem das operações por URLs SSH ou HTTPS.

  1. Crie um repositório 'remoto':

    $ git init --bare /mnt/Stick/Repositories/Large_Project.git
    
  2. No computador 1, envie tudo:

    $ cd ~/Large_Project
    $ git remote add usb /mnt/Stick/Repositories/Large_Project.git
    $ git push usb master
    
  3. No computador 2, bem, o mesmo de sempre.

    $ git remote add usb /mnt/Stick/Repositories/Large_Project.git
    $ git pull usb
    

(Você também pode enviar / buscar / puxar diretamente de um URL ou caminho.)

Método 1b (rede interna): se você tiver um servidor interno com SSH disponível e se o Git estiver instalado, poderá fazer o mesmo como acima , basta especificar um endereço SSH usando a sintaxe [user@]host:pathou ssh://[user@]host/path.

  1. Crie um repositório 'remoto' executando git init --bare <somepath.git>no servidor designado (via SSH).

  2. No computador 1, da mesma maneira como demonstrado anteriormente.

    $ git remote add origin myserver.example.com:Gits/Large_Project.git
    

    Ou se você preferir:

    $ git remote add origin ssh://myserver.example.com/Gits/Large_Project.git
    
  3. No computador 2, novamente o mesmo que o método 1a.


Método 2: você pode criar 'pacotes de transferência' que arquivam uma determinada lista de confirmações em um único arquivo.

Infelizmente, os comandos do pacote configurável não se lembram automaticamente do que já foi fornecido da última vez; portanto, é necessário marcação manual ou manutenção de notas. Vou apenas pegar os exemplos do manual git-bundle.

  1. No computador 1, crie um pacote de toda a ramificação:

    $ cd ~/Large_Project
    $ git bundle create /mnt/Stick/Project.bundle master
    $ git tag -f last-bundled master
    
  2. No computador 2, retire do pacote como se fosse um repositório:

    $ cd ~/Large_Project
    $ git pull /mnt/Stick/Project.bundle
    

Os pacotes subsequentes não precisam compactar o todo master- eles podem compactar apenas os commits recém-adicionados last-bundled..master.

  1. No computador 1, crie um pacote de confirmações recém-adicionadas:

    $ cd ~/Large_Project
    $ git bundle create /mnt/Stick/Project.bundle last-bundled..master
    $ git tag -f last-bundled master
    
  2. O mesmo que acima.

gravidade
fonte
Na verdade, não seria ruim para os meus propósitos, também em git nada é "primário", como cada repositório tem toda a história, para que possa recriá-lo cada vez que algo vai mal
Tutu Kaeen
manual tagging or note-keeping is needed, Uma opção a menos que o repo é muito grande é: git bundle create my.bundle --all, ele deve conter tudo
birdspider
Gosto mais dessa resposta, pois é mais ilustrativa, mesmo que a resposta aceita e isso diga a mesma coisa.
Rystraum
Qual é o significado da opção "nua"?
Lightness Races em órbita
11
Ele cria um repositório que é apenas o banco de dados (o que você normalmente encontraria na .git/pasta oculta), sem uma 'árvore de trabalho' (os arquivos editáveis). É a forma preferida para os repositórios que você git pushdeseja.
grawity
20

git bundle create

Um dos métodos é usar armazenamento externo para trocar dados entre repositórios é o git bundle . Dessa forma, você possui apenas arquivos únicos para cada transferência, não repositórios intermediários do Git.

Cada "git push" se transforma em criação de um arquivo, "git fetch" busca coisas desse arquivo.

Sessão de demonstração

Criando o primeiro repositório e executando o primeiro "push"

gitbundletest$ mkdir repo1

gitbundletest$ cd repo1

repo1$ git init
Initialized empty Git repository in /tmp/gitbundletest/repo1/.git/
repo1$ echo 1 > 1 && git add 1 && git commit -m 1
[master (root-commit) c8b9ff9] 1
 1 file changed, 1 insertion(+)
 create mode 100644 1

repo1$ git bundle create /tmp/1.bundle master HEAD
Enumerating objects: 3, done.
Counting objects: 100% (3/3), done.
Writing objects: 100% (3/3), 384 bytes | 384.00 KiB/s, done.
Total 3 (delta 0), reused 0 (delta 0)

"clonagem" para o segundo repositório (ou seja, o segundo computador):

gitbundletest$ git clone /tmp/1.bundle repo2
Cloning into 'repo2'...
Receiving objects: 100% (3/3), done.

gitbundletest$ cd repo2/

repo2$ cat 1
1

Fazendo algumas alterações e "enviando-as" para outro arquivo de pacote configurável:

repo2$ echo 2 > 1 && git add 1 && git commit -m 2
[master 250d387] 2
 1 file changed, 1 insertion(+), 1 deletion(-)

repo2$ git bundle create /tmp/2.bundle origin/master..master origin/HEAD..HEAD
Enumerating objects: 5, done.
Counting objects: 100% (5/5), done.
Writing objects: 100% (3/3), 415 bytes | 415.00 KiB/s, done.
Total 3 (delta 0), reused 0 (delta 0)

"pull" muda para o primeiro repositório:

repo2$ cd ../repo1

repo1$ git pull /tmp/2.bundle 
Receiving objects: 100% (3/3), done.
From /tmp/2.bundle
 * branch            HEAD       -> FETCH_HEAD
Updating c8b9ff9..250d387
Fast-forward
 1 | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

repo1$ cat 1
2

Ao contrário do primeiro pacote, o segundo contém apenas histórico parcial do Git e não é diretamente clonável:

repo1$ cd ..

gitbundletest$ git clone /tmp/2.bundle repo3
Cloning into 'repo3'...
error: Repository lacks these prerequisite commits:
error: c8b9ff94942039469fa1937f6d38d85e0e39893a 
fatal: bad object 250d38747656401e15eca289a27024c61e63ed68
fatal: remote did not send all necessary objects

Há uma desvantagem no uso de pacotes configuráveis ​​que você precisa especificar manualmente qual intervalo de confirmações cada pacote configurável deve conter. Ao contrário git push, git bundlenão acompanha o que estava no pacote anterior, é necessário ajustar manualmente refs/remotes/origin/masterou os pacotes seriam maiores do que poderiam ser.

Vi.
fonte
Não se esqueça de mencionar a --allbandeira para obter tudo. Se o repo for pequeno o suficiente, esse é o processo mais simples, pois você simplesmente transfere tudo sempre! Apenas não perca o cartão de memória - provavelmente o maior problema de segurança!
Philip Oakley
7

Você precisa primeiro instalar o Git . Em seguida, para criar um novo repositório, execute dentro da pasta que você copiou:

git init

Em seguida, você pode adicionar os arquivos que deseja controlar a versão git add(adicionar -apara todos os arquivos) e começar a confirmar as alterações ( git commit).

Você não precisa enviar para nenhum controle remoto, pois pode trabalhar no seu histórico local ( git log).

Para mais informações, verifique:


Empurrar / puxar sem internet

Usando o git pushcomando, é possível enviar por SSH (usando conexão local, intranet):

git remote add server ssh://[user@]host.xz[:port]/path/to/dev/repo.git/
git push server

ou empurrando para a pasta:

git push /mnt/usb/my_repo

Isso pressupõe que você tenha duas cópias do seu repositório.

O mesmo com puxar, por exemplo

git pull /mnt/usb/my_repo

Remendo

Para aplicar patches, você pode usar o patchcomando ou git apply.

Consulte: Criar arquivo de correção ou diff a partir do repositório git e aplicá-lo a outro repositório git diferente .

kenorb
fonte
5

Você também pode usar o Git localmente. Seus commits são armazenados apenas localmente, e você ainda possui controle de versão (e pode diferir / mesclar etc.), mas você simplesmente não pode acessar o repositório a partir de qualquer outro computador.

Você pode iniciar um repositório Git local executando git initna sua pasta local. Como descrito aqui .

dhae
fonte
3
que eu sei, mas eu quero trabalhar em outro computador e aplicá-lo aos arquivos no servidor que não têm acesso à Internet
Tutu Kaeen
2
@TutuKaeen Não vejo nada de errado em ter o repositório em uma unidade flash e apenas cloná-lo / sincronizá-lo em discos rígidos de computadores diferentes. No entanto, "servidor sem acesso à Internet" parece estranho, o objetivo de um servidor é fornecer um serviço, na maioria das vezes o serviço está relacionado à rede (mas nem sempre, de fato).
AnonymousLurker
2
@dhae - Reserve um momento para fornecer mais detalhes sobre como usar o Git localmente. Apenas indicar que isso pode ser feito não é uma resposta útil.
Ramhound #
2
@anonymousLurker, a veiculação está veiculando dados em rede fechada em uma instituição muito importante. Simplesmente não serve nada para a Internet ampla, pois os dados são muito delicados e apenas para os funcionários.
Tutu Kaeen
11
@TutuKaeen: Se houver algum acesso à rede, você sempre poderá executar seu próprio servidor Git via SSH. Há mais no Git do que apenas no GitHub.
grawity