La configuration de git pilote d'ignorer un dossier sur la fusion

j'ai déjà fait une recherche approfondie, j'ai lu beaucoup de questions et de solutions et je l'ai essayé de différentes façons, mais j'ai été incapable de faire ce que je veux, ce qui est assez simple.

j'ai la branche principale, où réside tout le code principal, et la branche de conception, où la disposition de l'application rails est construite par l'équipe de conception. Ils ont ajouté un dossier appelé "photoshop" au dossier public pour garder leurs sources pour les images également sous le contrôle de la version. Mais je ne veux pas que ce dossier soit copié sur merge vers la branche master parce que, bien, il n'est pas nécessaire.

apparemment, la façon de faire ceci est à travers un pilote de fusion. Donc, j'ai créé le pilote" ignore":

[merge "ignore"]
name = always ignore during merge
driver = ignore.sh %0 %A %B

et a créé le ignore.sh file on my $PATH:

exit 0

j'ai créé le .gitattributes file inside public/, parce que le dossier photoshop doit être ignoré en entier et qu'il va apparaître sous public/:

photoshop  merge=ignore
photoshop/ merge=ignore
photoshop/* merge=ignore
photoshop/**/* merge=ignore

comme vous pouvez le voir, j'ai essayé plusieurs modèles différents d'ignorer l'ensemble du dossier, mais cela ne fonctionne pas. Je crois que c'est parce qu'il n'y a pas de dossier sur la branche principale, donc il n'y a pas de conflit et donc git n'utilise pas le pilote ignore. Y a-t-il un moyen d'y parvenir sans avoir à créer un dossier public/photoshop sur master?

Merci!

12
demandé sur Felipe Koch 2010-06-24 19:39:45

3 réponses

comme le suggère mon autre réponse, voici la version étendue, généralisée, industrielle de la solution.

(Oui, je m'ennuyais à la maison et je n'avais rien de mieux à faire :P)

ce script va ajouter un nouveau, detached commit basé sur votre Local design branch, de sorte qu'il n'affectera ni le dépôt de design ni votre branche de design. La livraison aura tous les fichiers supprimés. Puis il effectue la fusion.

pour ceux qui sont trop paresseux pour lire le code complet, le" noyau "de ces étapes peut être simplifié comme suit:

original=$(gitbranch HEAD)    # current branch name, or sha1 if not in a branch
branchsha=$(gitsha "$branch") # sha1 of a ref, to force detached commit

git checkout "$branchsha"   &&
git rm -rf "${files[@]}"    &&
git commit -m "$msgcommit"  &&
newsha=$(gitsha HEAD)       &&
git checkout "$original"    &&
git merge -m "$msgmerge" "${mergeopts[@]}" "$newsha"

et voici le script complet:

(un peu modifié pour faire face à la faible et limitée couleur de la syntaxe de SO, il est donc préférable d'obtenir la source Vierge à partir du lien ci-dessous)

git-bande-fusion

#!/bin/bash
#
# git-strip-merge - a git-merge that delete files on branch before merging
#
#    Copyright (C) 2012 Rodrigo Silva (MestreLion) <linux@rodrigosilva.com>
#
#    This program is free software: you can redistribute it and/or modify
#    it under the terms of the GNU General Public License as published by
#    the Free Software Foundation, either version 3 of the License, or
#    (at your option) any later version.
#
#    This program is distributed in the hope that it will be useful,
#    but WITHOUT ANY WARRANTY; without even the implied warranty of
#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#    GNU General Public License for more details.
#
#    You should have received a copy of the GNU General Public License
#    along with this program. If not see <http://www.gnu.org/licenses/gpl.html>
#
# Answer for "How to setup a git driver to ignore a folder on merge?"
# See /q/how-to-setup-a-git-driver-to-ignore-a-folder-on-merge-3403/"remove files from '<branch>' before merge"
msgmerge="Merge stripped branch '<branch>'"
verbose=0
quiet=(--quiet)

usage() {
    cat <<- USAGE
    Usage: $myname [git-merge options] [-M <commitmsg>] <branch> FILE...
    USAGE
    if [[ "" ]] ; then
        cat >&2 <<- USAGE
        Try '$myname --help' for more information.
        USAGE
        exit 1
    fi
    cat <<-USAGE

    "git-merge that delete files on "foreign" <branch> before merging

    Useful for ignoring a folder in <branch> before merging it with
    current branch. Works by deleting FILE(S) in a detached commit based
    on <branch>, and then performing the merge of this new commit in the
    current branch. Note that <branch> is not changed by this procedure.
    Also note that <branch> may actually be any reference, like a tag,
    or a remote branch, or even a commit SHA.

    For more information, see </q/how-to-setup-a-git-driver-to-ignore-a-folder-on-merge-3403/"$msgcommit"

      -m <message>, --message=<message>
         message for the merge commit. Since we are not merging <branch>
         directly, but rather a detached commit based on it, we forge a
         message similar to git's default for a branch merge. Otherwise
         git would use in message the full and ugly SHA1 of our commit.
         Default message is: "$msgmerge"

      For both commit messages, the token "<branch>" is replaced for the
      actual <branch> name.

    Additional options are passed unchecked to git merge.

    All options must precede <branch> and FILE(s), except -h and --help
    that may appear anywhere on the command line.

    Example:
      $myname design "photoshop/*"

    Copyright (C) 2012 Rodrigo Silva (MestreLion) <linux@rodrigosilva.com>
    License: GPLv3 or later. See <http://www.gnu.org/licenses/gpl.html>"
    USAGE
    exit 0
}

# Helper functions
myname="${0##*/}"
argerr()  { printf "%s: %s\n" "${0##*/}" "${1:-error}" >&2 ; usage 1 ; }
invalid() { argerr "invalid option: " ; }
missing() { argerr "missing ${2:+ }operand${1:+ from }." ; }

# Option handling
files=()
mergeopts=()
for arg in "$@"; do case "$arg" in -h|--help) usage ;; esac; done
while (( $# )); do
    case "" in
    -v|--verbose  ) verbose=1            ;;
    -M            ) shift ; msgcommit= ;;
    -m            ) shift ; msgmerge=  ;;
    --msgcommit=* ) msgcommit=${1#*=}    ;;
    --message=*   ) msgmerge=${1#*=}     ;;
    -*            ) mergeopts+=( "" )  ;;
    *             ) branch=""
                    shift ; break        ;;
    esac
    shift
done
files+=( "$@" )

# Argument handling

msgcommit=${msgcommit//<branch>/$branch}
msgmerge=${msgmerge//<branch>/$branch}

[[ "$msgcommit" ]]  || missing "msgcommit" "MSG"
[[ "$branch"   ]]   || missing ""          "<branch>"
(( ${#files[@]} ))  || missing ""          "FILE"

((verbose)) && quiet=()

# Here the fun begins...
gitsha()    { git rev-parse "" ; }
gitbranch() {
    git symbolic-ref "" 2> /dev/null | sed 's/refs\/heads\///' ||
    gitsha ""
}

original=$(gitbranch HEAD)
branchsha=$(gitsha "$branch")

trap 'git checkout --quiet "$original"' EXIT

git checkout "$branchsha"  "${quiet[@]}" &&
git rm -rf "${files[@]}"   "${quiet[@]}" &&
git commit -m "$msgcommit" "${quiet[@]}" &&
newsha=$(gitsha HEAD)                    &&
git checkout "$original"   "${quiet[@]}" &&
git merge -m "$msgmerge" "${mergeopts[@]}" "$newsha"

Profitez-en!

Une image vaut plus que mille mots...

avant la fusion:

enter image description here

après fusion:

enter image description here

notez que la pointe de la branche" design " n'a pas été affectée du tout, même si c'est une branche locale, grâce à l'astuce de commit détachée. Autre que cela, les deux les commits (la suppression et la fusion) sont des commits réguliers, avec des messages de commit appropriés et des parents. Et la branche" master " est débarrassée de tous les fichiers indésirables.

16
répondu MestreLion 2012-04-19 09:29:40

pas une réponse en soi , mais quelques notes sur .gitignore : il sera pas vous aider dans votre scénario.

.gitignore est pour ignorer les fichiers de arbre de travail pour être ajouté à index (aire de repos). Il n'est donc efficace que lorsque vous utilisez git add <files> , et il peut encore être dépassé en utilisant git add --force <files> . Il est destiné seulement comme une commodité pour empêcher les fichiers indésirables d'être ajouté, mais il a aucun effet sur les fichiers à l'intérieur du dépôt

dans votre scénario, .gitignore n'est pas nécessaire, puisque vous n'avez pas de dossier local ./photoshop , donc vous n'aurez jamais de fichiers photoshop à ajouter à votre branche principale. Il ne serait pas mal, cependant, de créer un juste au cas où. Et pour l'équipe de conception .gitignore n'est pas la bienvenue, car ils want les fichiers photoshop à ajouter à leur branche.

donc, puisque merge traite avec committed data , et ./photoshop fichiers sont déjà à l'intérieur du dépôt, votre approche d'utiliser un pilote de fusion était correcte.

le problème est... par défaut, un pilote de fusion n'est déclenché qu'en cas de conflits . Et, depuis master succursale ne ont tout ./photoshop dossier ou des fichiers, il n'y a pas de conflits du tout , ils sont proprement fusionnés. Donc, votre pilote de fusion n'a pas eu d'effet, indépendamment de vos trajectoires (au fait, votre 2e pilote, photoshop/ , était le bon). Je ne sais pas si git merge peut être configuré pour déclencher un pilote de fusion même pour les fichiers non-conflictuels, mais cela vaut la peine de googler.

comme je l'ai déjà dit, ma réponse n'est pas une VRAIE solution à votre problème. Je j'espérais juste apporter un peu de lumière sur le sujet, en expliquant pourquoi vos tentatives d'utiliser le pilote de fusion et .gitignore ont échoué. Je suggère de lire plus sur les pilotes de fusion (configuration). Aussi submodules est intéressant d'étudier.

Espérons que cette aide!

mise à JOUR

peut-être que mon autre réponse vous aidera :

Usage: git-strip-merge [git-merge options] [-M <commitmsg>] <branch> FILE...

git-bande-fusion

Profitez-en!

10
répondu MestreLion 2017-05-23 12:24:34

avez-vous essayé d'ajouter un fichier .gitignore dans votre branche master , pour ignorer tout contenu de répertoire photopshop ?

Ensuite, une fusion de design à master ne devrait pas ajouter ce nouveau répertoire dans master .

si cela fonctionne, vous avez encore besoin d'un pilote de fusion, mais cette fois pour gérer le contenu du fichier .gitignore .

0
répondu VonC 2010-06-24 16:23:02