web-dev-qa-db-fra.com

Git peut-il ignorer une ligne spécifique?

J'utilise git pour synchroniser avec phonegap pendant les tests sur le navigateur natif du téléphone. En tant que tel, j'ai la ligne suivante:

var isPhoneGap = false;

Évidemment, je change cela lors de la construction, mais y a-t-il un moyen de configurer git pour ignorer cette seule ligne ou dois-je aller le mettre dans son propre fichier et l'ignorer de cette façon?

J'utilise Gitx et le terminal sur OSX 10.6.

92
Iolo

Si votre fichier est d'un type spécifique, vous pouvez déclarer un pilote de filtre de conten , que vous pouvez déclarer dans un .gitattributes fichier (tel que présenté dans "Expansion des mots clés" de " Attributs Git "):

http://git-scm.com/figures/18333fig0702-tn.png

*.yourType filter=yourFilterName

(vous pouvez même définir ce filtre pour un fichier spécifique , si vous le souhaitez)

Mettre en place:

  • yourFilterName.smudge (déclenché le git checkout) et

    git config --global filter.yourFilterName.smudge 'sed "s/isPhoneGap = .*/isPhoneGap = true/"'
    
  • yourFilterName.clean (déclenché le git add)

    git config --global filter.yourFilterName.clean 'sed "s/isPhoneGap = .*/isPhoneGap = false/"'
    

Votre fichier apparaîtra inchangé le git status, mais sa version extraite aurait la bonne valeur pour isPhoneGap.

86
VonC

Vous pouvez utiliser

git update-index --assume-unchanged [file]

pour ignorer les modifications d'un fichier que vous ne souhaitez pas suivre. J'utilise cette solution lorsque j'ai besoin d'avoir un fichier dans le référentiel mais ce fichier a des parties qui changent et dont je n'ai pas toujours besoin de suivre.

Lorsque le fichier contient des modifications importantes, vous devez procéder comme suit:

git update-index --no-assume-unchanged [file]

Voir aussi Git doc update-index pour --[no-]assume-unchanged paramètre.

Lorsque ces indicateurs sont spécifiés, les noms d'objet enregistrés pour les chemins d'accès ne sont pas mis à jour. Au lieu de cela, ces options définissent et désactivent le bit "supposer inchangé" pour les chemins. Lorsque le bit "supposer inchangé" est activé, git arrête de vérifier les fichiers de l'arborescence de travail pour d'éventuelles modifications, vous devez donc désactiver manuellement le bit pour indiquer à git lorsque vous modifiez le fichier de l'arborescence de travail.

35
Carlos

Gitx devrait vous permettre de valider ou d'ignorer des lignes individuelles (vous le savez peut-être déjà), mais vous devrez le faire à chaque fois que vous vous engagez. Je pense qu'il serait préférable d'avoir un fichier de configuration par cible de déploiement (vous pouvez les versionner) et certains paramètres d'exécution pour la façon dont vous démarrez le serveur (comme ./myserver --config=whatever.js).

6
Andy Ray

Continue https://stackoverflow.com/a/20574486/4935114 , @ Mike a proposé de créer un pre-commit hook qui va grep dans les fichiers intermédiaires pour les lignes que l'on pourrait ignorer. Le hook vérifie si ces lignes ont été mises en scène. Si c'est le cas, il echo est un avertissement et il exit est avec le code 1 pour que le processus de validation ne se poursuive pas.

Inspiré par @ la réponse de Mike , je me suis retrouvé à utiliser peut-être une version améliorée de son hook qui automatiquement resets (avec le -p flag) la ligne spécifique que nous voulons ignorer.

Je ne suis pas sûr que ce crochet fonctionnera dans une situation où vous avez de nombreux fichiers avec cette ligne à ignorer, mais ce pre-commit hook recherche une modification dans cette ligne dans un fichier spécifique buildVars.Java. Le script du crochet ressemblait à ceci lorsque je l'ai testé sur ma machine.

#!/bin/sh

# this hook looks for lines with the text `var isPhoneGap = false;` in the file `buildVars.Java` and it resets these lines to the previous state before staged with `reset -p`

if [[ $(git diff --no-ext-diff --cached buildVars.Java | grep --count -e "var\ isPhoneGap[\ ]*=[\ ]*") -ne 0 ]]; then
    cat <<EOW
WARNING: You are attempting to commit changes which are not supposed to be commited according to this \`pre-commit\` hook
This \`pre-commit\` hook will reset all the files containing this line to it's previous state in the last commit.
EOW
    echo /$'\n'isPhoneGap$'\n'y$'\n'q | git reset -p
    # BONUS: Check if after reseting, there is no actual changes to be commited and if so, exit 1 so the commit process will abort.
    if [[ $(git diff --no-ext-diff --cached | wc -l) -eq 0 ]]; then
        echo there are no actual changes to be commited and besides the change to the variable \'isPhoneGap\' so I won\'t commit.
        exit 1
    fi
fi

Explication

J'ai fait écho à une séquence de contrôle qui recherche l'expression régulière isPhoneGap au cours d'un processus interactif reset. Émulant ainsi un utilisateur qui appuie sur / pour rechercher isPhoneGap, appuie sur y lorsqu'on lui demande s'il souhaite supprimer ce correctif et enfin appuie sur q pour quitter le reset interactif.

Le processus de patch inversé interactif est documenté ici: https://git-scm.com/docs/git-add#git-add-patch


REMARQUE: Le script ci-dessus en supposant que la variable interactive.singleKey est false. Si vous avez configuré le vôtre sur true, supprimez tout $'\n' à partir de la commande echo juste après l'avertissement.

4
Doron Behar

Voici comment vous pouvez le faire avec filtres git :

  1. Créer/ouvrir un fichier gitattributes:
    • <racine du projet> /. gitattributes (sera validé dans le référentiel)
      OU
    • <racine du projet> /. git/info/attributs (ne sera pas validé dans le référentiel)
  2. Ajoutez une ligne définissant les fichiers à filtrer:
    • *.rb filter=gitignore, c'est-à-dire exécuter un filtre nommé gitignore sur tous les *.rb des dossiers
  3. Définissez le filtre gitignore dans votre gitconfig:
    • $ git config --global filter.gitignore.clean "sed '/#gitignore$/'d", c'est-à-dire supprimer ces lignes
    • $ git config --global filter.gitignore.smudge cat, c'est-à-dire ne rien faire lors de l'extraction d'un fichier du référentiel

Remarques:
Bien sûr, cela concerne les fichiers Ruby, appliqués lorsqu'une ligne se termine par #gitignore, appliqué globalement dans ~/.gitconfig. Modifiez-le selon vos besoins.

Attention!!
Cela laisse votre fichier de travail différent du dépôt (bien sûr). Toute vérification ou rebasage entraînera la perte de ces lignes! Cette astuce peut sembler inutile car ces lignes sont perdues à plusieurs reprises lors de l'extraction, du rebasage ou de l'extraction, mais j'ai un cas d'utilisation spécifique afin de l'utiliser.

Juste git stash save "proj1-debug" pendant que le filtre est inactif (désactivez-le temporairement dans gitconfig ou quelque chose du genre). De cette façon, mon code de débogage peut toujours être git stash apply 'd à mon code à tout moment sans craindre que ces lignes ne soient accidentellement commises.

J'ai une idée possible pour résoudre ces problèmes, mais je vais essayer de l'implémenter une autre fois.

Merci à Rudi et jw013 pour avoir mentionné les filtres git et les attributs git.

3
Kache

Un pilote de filtre de contenu n'est pas une bonne solution. Vous pourrez peut-être masquer cette ligne de git status/etc mais ce n'est pas vraiment ignoré. Dès que vous modifiez la valeur, votre répertoire de travail sera marqué comme sale même si la modification peut ne pas être visible.

Si vous voulez vraiment que cette ligne sorte du contrôle de version, la changer en argument de ligne de commande ou la placer dans un fichier d'inclusion ou de construction ignoré peut être le seul moyen pratique.

2
patricktokeeffe

Je suppose que cela pourrait être quelque chose qui apparaît dans plus d'une ligne de votre source.

Je pense qu'il serait plus propre d'avoir un fichier .userbuildconfig que vous venez d'inclure et d'avoir les valeurs par défaut enregistrées. Ensuite, vous pouvez utiliser suggestion de Carlos pour marquer ce fichier seul comme supposé inchangé. De cette façon, d'autres modifications du fichier dont vous devez vérifier le paramètre ne sont pas manquées.

Cela peut vous permettre de régler les macros de préprocesseur localement (ou pour Java quelque chose comme ça https://stackoverflow.com/a/1813873/1270965 ).

1
johnb003