Git clona una versione particolare del repository remoto


181

Ho clonato un repository git remoto circa un mese fa. Il repository remoto ha subito molte modifiche e ora è diventato instabile. Ora ho bisogno di un'altra copia del repository, versione identica a quella che ho clonato un mese fa.

Come faccio a fare questo?



Risposte:


242

È possibile "reimpostare" il repository su qualsiasi commit desiderato (ad es. 1 mese fa).

Usa git-reset per questo:

git clone [remote_address_here] my_repo
cd my_repo
git reset --hard [ENTER HERE THE COMMIT HASH YOU WANT]

27
Non lo hai menzionato, ma questo ripristinerà solo il masterramo, che è estratto di default su un clone. Se un ramo diverso dal mastertuo principale ramo di sviluppo deve essere verificato primagit reset
Steve Folly

16
perché non dovresti fare un semplice checkout del commit desiderato?
nemoo,

10
Perché ti ritroverai nello stato "scollegato HEAD" dopo il checkout per un particolare commit.
Rui Carneiro,

6
@RuiCarneiro sarebbe meglio usarti per git checkout -b new_branch hashcreare un nuovo ramo basato sull'hash senza toccare nessun altro ramo. Spostare la testa di un ramo esistente potrebbe causare problemi quando è il momento di inviare qualcosa a un server remoto.
Loïc Faure-Lacroix il

1
@YuriGhensev Se il commit è stato già inviato a un ramo remoto git pull origin [branch], altrimenti puoi farlo , perduto.
Rui Carneiro,

94

Puoi usare semplicemente

git checkout  commithash

in questa sequenza

git clone `URLTORepository`
cd `into your cloned folder`
git checkout commithash

commit hash si presenta così "45ef55ac20ce2389c9180658fdba35f4a663d204"


9
Mi piace questa risposta al meglio. Penso che un git reset --harddovrebbe essere evitato, a favore di un git checkout commit-hash. A git reset --hardrimuove parte della storia di Git che a volte non è desiderabile.
Jordan Stewart,

8
git initnon è necessario
Lautaro Paskevicius,

37

Utilizzare git logper trovare la revisione a cui si desidera eseguire il rollback e prendere nota dell'hash di commit. Successivamente, hai 2 opzioni:

  1. Se prevedi di eseguire il commit di qualcosa dopo tale revisione, ti consiglio di effettuare il checkout in una nuova filiale:git checkout -b <new_branch_name> <hash>

  2. Se non prevedi di eseguire il commit di nulla dopo tale revisione, puoi semplicemente effettuare il checkout senza un ramo: git checkout <hash>- NOTA: questo metterà il tuo repository in uno stato "HEAD distaccato", il che significa che attualmente non è collegato a nessun ramo - quindi tu " Avremo del lavoro extra per unire i nuovi commit in un ramo reale .

Esempio:

$ git log
commit 89915b4cc0810a9c9e67b3706a2850c58120cf75
Author: Jardel Weyrich <suppressed>
Date:   Wed Aug 18 20:15:01 2010 -0300

    Added a custom extension.

commit 4553c1466c437bdd0b4e7bb35ed238cb5b39d7e7
Author: Jardel Weyrich <suppressed>
Date:   Wed Aug 18 20:13:48 2010 -0300

    Missing constness.

$ git checkout 4553c1466c437bdd0b4e7bb35ed238cb5b39d7e7
Note: moving to '4553c1466c437bdd0b4e7bb35ed238cb5b39d7e7'
which isn't a local branch
If you want to create a new branch from this checkout, you may do so
(now or later) by using -b with the checkout command again. Example:
  git checkout -b <new_branch_name>
HEAD is now at 4553c14... Missing constness.

In questo modo non perdi alcuna informazione, quindi puoi passare a una revisione più recente quando diventa stabile.


2
Ma anche che sei su una testa staccata, il che è OK per le operazioni di sola lettura. Ma quando si intende apportare modifiche a partire da questa revisione, è necessario creare un nuovo ramo. Vedi sitaramc.github.com/concepts/detached-head.html per maggiori informazioni.
Rudi,

@Rudi: grazie. Era solo un esempio per mostrare l'utilizzo. Aggiornato per menzionarlo.
jweyrich,

Per tornare allo "stato di lavoro" puoi semplicemente git checkout developdove sviluppa è il nome del tuo ramo.
Steve Tauber,

1
@SteveTauber bene, supponendo che tu abbia un ramo diverso che sta funzionando , cambiare in quel ramo è davvero abbastanza.
jweyrich,

19

Se quella versione che devi ottenere è un ramo o un tag, allora:

git clone -b branch_or_tag_name repo_address_or_path

2

A differenza dei sistemi di controllo versione centralizzato, Git clona l'intero repository, quindi non solo ottieni i file remoti correnti, ma l'intera cronologia. Il repository locale includerà tutto questo.

Potrebbero esserci stati dei tag per contrassegnare una versione particolare al momento. Altrimenti, puoi crearli tu stesso localmente. Un buon modo per farlo è usare git logo forse più visivamente con strumenti come gitk(forse gitk --allper vedere tutti i rami e i tag). Se riesci a individuare gli hash di commit utilizzati in quel momento, puoi taggarli usando git tag <hash>e quindi controllarli in nuove copie funzionanti (ad esempio git checkout -b new_branch_name tag_nameo direttamente con l'hash invece del nome del tag).


1

Puoi risolverlo in questo modo:

git reset --hard sha

dove shaad es .:85a108ec5d8443626c690a84bc7901195d19c446

Puoi ottenere lo sha desiderato con il comando:

git log

1

uploadpack.allowReachableSHA1InWant

Dal momento che Git 2.5.0 questa variabile di configurazione può essere abilitata sul server, qui la richiesta della funzione GitHub e il commit GitHub abilitano questa funzione .

Bitbucket Server lo ha abilitato dalla versione 5.5+ .

Uso:

# Make remote with 4 commits, and local with just one.
mkdir server
cd server
git init
touch 1
git add 1
git commit -m 1
git clone ./ ../local
for i in {2..4}; do
    touch "$i"
    git add "$i"
    git commit -m "$i"
done

# Before last commit.
SHA3="$(git log --format='%H' --skip=1 -n1)"
# Last commit.
SHA4="$(git log --format='%H' -n1)"

# Failing control without feature.
cd ../local
# Does not give an error, but does not fetch either.
git fetch origin "$SHA3"
# Error.
git checkout "$SHA3"

# Enable the feature.
cd ../server
git config uploadpack.allowReachableSHA1InWant true

# Now it works.
cd ../local
git fetch origin "$SHA3"
git checkout "$SHA3"
# Error.
git checkout "$SHA4"

0

L'albero dei sorgenti che stai richiedendo è ancora disponibile all'interno del repository git, tuttavia, avrai bisogno dello SHA1 del commit che ti interessa. Presumo che tu possa ottenere lo SHA1 dal clone corrente che hai?

Se riesci a ottenere quel SHA1, puoi creare un branch / reset lì per avere lo stesso repository.

Comandi secondo la risposta di Rui


0

Probabilmente git resetrisolve il tuo problema.

git reset --hard -#commit hash-
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.