Est-il possible de récupérer un seul commit spécifique à partir d'un dépôt Git distant sans le cloner sur mon PC? La structure de repo à distance est absolument identique à celle de la mienne et par conséquent, il n'y aura pas de conflits, mais je ne sais pas comment faire cela et je ne veux pas cloner cet énorme référentiel.
Je suis nouveau à git, y at-il un moyen?
À partir de la version 2.5 + de Git (T2 2015), il est en fait possible d'extraire un seul commit (sans cloner le référentiel complet).
Voir commit 68ee628 par Fredrik Medley (moroten
) , 21 mai 2015.
(Fusionné par Junio C Hamano - gitster
- dans commit a9d349 , 01 juin 2015)
Vous avez maintenant une nouvelle configuration (côté serveur)
_uploadpack.allowReachableSHA1InWant
_
Autoriser _
upload-pack
_ à accepter une demande d'extraction demandant un objet accessible à partir de toute info-bulle. Cependant, notez que le calcul de l'accessibilité aux objets est coûteux en calcul.
La valeur par défaut estfalse
.
Si vous combinez cette configuration côté serveur avec un clone peu profond ( git fetch --depth=1
), vous pouvez demander un seul commit (voir t/t5516-fetch-Push.sh
).
_git fetch --depth=1 ../testrepo/.git $SHA1
_
Vous pouvez utiliser la commande _git cat-file
_ pour voir que la validation a été extraite:
_git cat-file commit $SHA1
_
"_
git upload-pack
_" qui sert "_git fetch
_" peut servir à exécuter des commits qui ne se trouvent pas à l'extrémité d'un ref, tant qu'ils sont accessibles à partir d'une référence, avec la variable de configuration _uploadpack.allowReachableSHA1InWant
_ .
La documentation complète est:
_
upload-pack
_: autoriser éventuellement l'extraction accessible sha1Lorsque l'option de configuration _
uploadpack.allowReachableSHA1InWant
_ est définie côté serveur, "_git fetch
_" peut faire une demande avec une ligne "vouloir" qui nomme un objet qui n'a pas été annoncé (probablement d'avoir été obtenu hors bande ou d'un pointeur de sous-module).
Seuls les objets accessibles à partir des conseils de branche, c’est-à-dire l’union des branches annoncées et des branches cachées par _transfer.hideRefs
_, seront traités.
Notez qu’il ya un coût associé à la nécessité de parcourir l’historique pour vérifier l’accessibilité.Cette fonctionnalité peut être utilisée pour obtenir le contenu d'un certain commit pour lequel le sha1 est connu, sans qu'il soit nécessaire de cloner l'ensemble du référentiel, en particulier si une extraction superficielle est utilisée .
Les cas utiles sont, par exemple,.
- des référentiels contenant des fichiers volumineux dans l'historique,
- ne récupérant que les données nécessaires à une extraction de sous-module,
- lorsque vous partagez un sha1 sans préciser à quelle branche il appartient et dans Gerrit, si vous pensez en termes de commits au lieu de changer de numéro.
(L’affaire Gerrit a déjà été résolue par le biais de _allowTipSHA1InWant
_, chaque changement de Gerrit ayant un réf.)
Git 2.6 (Q3 2015) améliorera ce modèle.
Voir commit 2bc31d1 , commit cc118a6 (28 juil. 2015) par Jeff King (peff
) .
(Fusion par Junio C Hamano - gitster
- dans commit 824a0be , 19 août 2015)
refs
: support négatif _transfer.hideRefs
_Si vous masquez une hiérarchie de références à l'aide de la configuration _
transfer.hideRefs
_, il n'existe aucun moyen de remplacer ultérieurement cette configuration pour la "révéler".
Ce patch implémente un masquage "négatif" qui permet de marquer immédiatement les correspondances comme non masquées, même si une autre correspondance les masquerait.
Nous prenons soin d’appliquer les allumettes dans l’ordre inverse de la façon dont elles nous sont fournies par la machine de configuration, afin que notre "dernier gagnant" gagne le travail de priorité de la configuration (et les entrées dans _.git/config
_ , par exemple, remplacera _/etc/gitconfig
_).Alors vous pouvez maintenant faire:
_git config --system transfer.hideRefs refs/secret
git config transfer.hideRefs '!refs/secret/not-so-secret'
_
masquer _
refs/secret
_ dans tous les dépôts, à l'exception d'un bit public dans un dépôt spécifique.
Git 2.7 (nov/déc 2015) va encore s'améliorer:
Voir commit 948bfa2 , commit 00b293e (05 nov. 2015), commit 78a766a , commit 92cab49 , commit 92cab49 , commit 92cab49 (03 nov. 2015), commit 00b293e , commit 00b293e (05 nov 2015), et commit 92cab49 , commit 92cab49 , commit 92cab49 , commit 92cab49 (03 nov. 2015) par Lukas Fleischer (lfos
) .
Aidé par: Eric Sunshine (sunshineco
) .
(Fusionnée par Jeff King - peff
- dans commit dbba85e , 20 nov. 2015)
_
config.txt
_: documenter la sémantique dehideRefs
avec des espaces de nomsÀ l'heure actuelle, il n'existe pas de définition claire du comportement de _
transfer.hideRefs
_ lorsqu'un espace de nommage est défini.
Expliquez quehideRefs
les préfixes correspondent aux noms supprimés dans ce cas. C'est ainsi que les modèleshideRefs
sont actuellement traités dans receive-pack.hideRefs: ajout du support pour faire correspondre les références complètes
En plus de faire correspondre les références supprimées, vous pouvez maintenant ajouter
hideRefs
motifs auxquels la référence complète (non séparée) correspond.
Pour distinguer les matchs dénudés des matchs complets, ces nouveaux modèles doivent être précédés d’un circumflexe (_^
_).
D'où le nouvelle documentation :
_transfer.hideRefs:
_
Si un espace de noms est en cours d'utilisation, le préfixe d'espace de noms est supprimé de chaque référence avant d'être mis en correspondance avec les modèles _
transfer.hiderefs
_.
Par exemple, si _refs/heads/master
_ est spécifié dans _transfer.hideRefs
_ et que l’espace de nommage actuel estfoo
, alors _refs/namespaces/foo/refs/heads/master
_ est omis des publications mais _refs/heads/master
_. et _refs/namespaces/bar/refs/heads/master
_ sont toujours annoncés sous la forme de lignes dites "avoir".
Afin de faire correspondre les références avant de supprimer, ajoutez un _^
_ devant le nom de la référence. Si vous combinez _!
_ et _^
_, _!
_ doit être spécifié en premier.
R .. mentionne dans les commentaires la configuration uploadpack.allowAnySHA1InWant
, ce qui permet à _upload-pack
_ d'accepter un fetch
demande qui demande n'importe quel objet. (La valeur par défaut est false
).
Voir commit f8edeaa (Nov. 2016, Git v2.11.1) par David "novalis" Turner (novalis
) :
_
upload-pack
_: autoriser éventuellement la récupération de sha1Il semble un peu idiot de faire une vérification de la vulnérabilité dans le cas où nous faisons confiance à l'utilisateur pour accéder à tout ce qui se trouve dans le référentiel.
En outre, il est racé dans un système distribué: un serveur peut annoncer une référence, mais un autre a depuis été forcé de s'exercer sur cette référence et les deux requêtes HTTP doivent être redirigées vers ces différents serveurs.
Vous ne clonez qu'une seule fois. Par conséquent, si vous avez déjà un clone du référentiel distant, son extraction ne téléchargera pas tout à nouveau. Indiquez simplement quelle branche vous souhaitez extraire, ou récupérez les modifications et extrayez le commit que vous souhaitez.
La récupération depuis un nouveau référentiel est très économique en bande passante, car elle ne téléchargera que les modifications que vous n'avez pas. Pensez en termes de Git faisant la bonne chose, avec une charge minimale.
Git stocke tout dans le dossier .git
. Un commit ne peut pas être récupéré et stocké isolément, il a besoin de tous ses ancêtres. Ils sont interdépendants .
Pour réduire la taille du téléchargement, vous pouvez cependant demander à git de ne récupérer que les objets liés à une branche ou à une validation spécifique:
git fetch Origin refs/heads/branch:refs/remotes/Origin/branch
Cela téléchargera uniquement les commits contenus dans la branche distante branch
(et seulement ceux qui vous manquent), et enregistrez-le dans Origin/branch
. Vous pouvez ensuite fusionner ou passer à la caisse.
Vous pouvez également spécifier uniquement un commit SHA1:
git fetch Origin 96de5297df870:refs/remotes/Origin/foo-commit
Cela téléchargera uniquement le commit du SHA-1 96de5297df870 spécifié (et de ses ancêtres manquants), et le stockera en tant que branche distante (non existante) Origin/foo-commit
.
J'ai tiré sur mon dépôt Git:
git pull --rebase <repo> <branch>
Permettre à Git de récupérer tout le code de la branche puis d’aller réinitialiser le commit qui m’intéressait.
git reset --hard <commit-hash>
J'espère que cela t'aides.
Vous pouvez simplement extraire un seul commit d'un dépôt distant avec
git fetch <repo> <commit>
où,
<repo>
peut être un nom de dépôt distant (par exemple, Origin
) ou même une URL de dépôt distant (par exemple, https://git.foo.com/myrepo.git
).<commit>
peut être le commit SHA1par exemple
git fetch https://git.foo.com/myrepo.git 0a071603d87e0b89738599c160583a19a6d95545
une fois que vous avez récupéré le commit (et les ancêtres manquants), vous pouvez simplement le vérifier avec
git checkout FETCH_HEAD
Notez que cela vous amènera à l'état "tête détachée".
Vous pouvez simplement aller chercher le dépôt distant avec:
git fetch <repo>
où,
<repo>
peut être un nom de dépôt distant (par exemple, Origin
) ou même une URL de dépôt distant (par exemple, https://git.foo.com/myrepo.git
).par exemple:
git fetch https://git.foo.com/myrepo.git
une fois que vous avez récupéré le dépôt, vous pouvez fusionner les commits que vous souhaitez (étant donné que la question concerne l'extraction d'un commit, vous pouvez utiliser la sélection par choix pour sélectionner un seul commit):
git merge <commit>
<commit>
peut être le commit SHA1par exemple:
git cherry-pick 0a071603d87e0b89738599c160583a19a6d95545
ou
git merge 0a071603d87e0b89738599c160583a19a6d95545
si vous souhaitez fusionner avec la dernière validation, vous pouvez également utiliser la variable FETCH_HEAD:
git cherry-pick (or merge) FETCH_HEAD
Cela fonctionne mieux:
git fetch Origin specific_commit
git checkout -b temp FETCH_HEAD
nommez "temp" comme vous voulez ... cette branche pourrait être orpheline
Enfin, j'ai trouvé un moyen de cloner un commit spécifique en utilisant git cherry-pick. En supposant que vous n’ayez aucun référentiel en local et que vous extrayiez un commit spécifique à distance,
1) créer un référentiel vide en local et git init
2) git remote add Origin " url-of-repository "
3) git fetch Origin [ceci ne déplacera pas vos fichiers dans votre espace de travail local à moins que vous ne fusionniez]
4) git cherry-pick " Entrez-longue-validation-hachage que vous ayez besoin "
Fait. De cette façon, vous aurez uniquement les fichiers de ce commit spécifique dans votre section locale.
Vous pouvez obtenir ceci en utilisant -> git log --pretty = oneline
Je pense que 'git ls-remote' ( http://git-scm.com/docs/git-ls-remote ) devrait faire ce que vous voulez. Sans forcer chercher ou tirer.
Si la validation demandée se trouve dans les demandes d'extraction du référentiel distant, vous pouvez l'obtenir par son ID:
# Add the remote repo path, let's call it 'upstream':
git remote add upstream https://github.com/repo/project.git
# checkout the pull ID, for example ID '60':
git fetch upstream pull/60/head && git checkout FETCH_HEAD