it-swarm.com.de

Wie kann ich das Zusammenführen eines bestimmten Zweigs in andere Zweige in Gitlab einschränken?

Gibt es eine Möglichkeit, das Zusammenführen von einer bestimmten Niederlassung in andere Niederlassungen einzuschränken? Lassen Sie mich erklären:

Ich habe einen Testzweig und einen Masterzweig in Gitlab. Das Team erstellt Feature-Zweige, führt sie in 'Testing' zur Genehmigung zusammen und führt dann den Feature-Zweig in 'Master' zusammen, sobald er genehmigt wurde.

Manchmal kann es Monate dauern, bis einige Funktionen genehmigt sind, und daher wird Code eine Weile in der Testbranche eingesetzt. In der Zwischenzeit wird möglicherweise ein anderer Feature-Zweig versuchen, sich zu 'testing' zusammenzuschließen, und Konflikte entstehen. Es wird jedoch erwartet, dass dies nur ein Mensch ist, und gelegentlich kann es vorkommen, dass jemand bei der Behandlung des Konflikts versehentlich Tests in seinen Feature-Zweig einbindet, was offensichtlich falsch ist. Stattdessen sollten wir zu "Testen" wechseln und unseren Feature-Zweig zu "Testen" zusammenführen, um den Konflikt innerhalb des Testzweigs zu bewältigen.

Jeder Rat ist willkommen.

6
David

Stellen Sie zunächst sicher, dass Ihre Bedürfnisse sehr normal und traditionell sind. Die Antwort ist ja.

So verhindern Sie das Zusammenführen von einem Zweig zu einem anderen, indem Sie einen Server-Git-Hook einrichten

Dies sind einige nützliche Links:

Um Ihnen zu helfen (und zum Spaß ^^), habe ich einen speziellen Hook in Python geschrieben, um Ihre spezifischen Anforderungen zu erfüllen (Sie müssen nur FORBIDDEN_SOURCE_BRANCH und FORBIDDEN_IF_NOT_DEST_BRANCH anpassen, wenn Sie mit einigen anderen Zweigen arbeiten möchten).

#!/bin/python
##
## Author: Bertrand Benoit <mailto:[email protected]>
## Description: Git Hook (server-side) allowing to prevent merge from some branches to anothers
## Version: 0.9

import sys, subprocess, re

FORBIDDEN_SOURCE_BRANCH='testing'
FORBIDDEN_IF_NOT_DEST_BRANCH='master'

# Considers only merge commit.
if not (len(sys.argv) >=2 and sys.argv[2] == 'merge'):
    sys.exit(0)

# Defines which is the source branch.
with open(sys.argv[1], 'r') as f:
    mergeMessage=f.readline()
mergeBranchExtract=re.compile("Merge branch '([^']*)'.*$").search(mergeMessage)
if not mergeBranchExtract:
    print('Unable to extract branch to merge from message: ', mergeMessage)
    sys.exit(0) # Ensures normal merge as failback

# Checks if the merge (source) branch is one of those to check.
mergeBranch=mergeBranchExtract.group(1)
if mergeBranch != FORBIDDEN_SOURCE_BRANCH:
  sys.exit(0) # It is NOT the forbidden source branch, so keeps on normal merge

# Defines which is the current branch.
currentBranchFullName=subprocess.check_output(['git', 'symbolic-ref', 'HEAD'])
currentBranchExtract=re.compile("^.*/([^/]*)\n$").search(currentBranchFullName)
if not currentBranchExtract:
  print('Unable to extract current branch from: ', currentBranchFullName)
  sys.exit(1) # Ensures normal merge as failback

# Checks if the current (destination) branch is one of those to check.
currentBranch=currentBranchExtract.group(1)
if currentBranch != FORBIDDEN_IF_NOT_DEST_BRANCH:
  print("FORBIDDEN: Merging from '" + mergeBranch + "' to '" + currentBranch + "' is NOT allowed. Contact your administrator. Now, you should use git merge --abort and keep on your work.")
  sys.exit(1) # This is exactly the situation which is forbidden

# All is OK, so keeps on normal merge
sys.exit(0)

Um all diese Arbeit zu teilen, habe ich ein neues Github-Repository erstellt, in das ich bei Bedarf weitere Hooks einfügen werde :)

Zur Information können Sie auch geschützte Zweige einrichten, um sie vor einigen Benutzern zu schützen

Dies ist die vollständige Dokumentation darüber.

Lassen Sie mich wissen, wenn Sie weitere Hilfe benötigen.

4
Bsquare ℬℬ

Sie möchten also, dass Ihr Hook vor dem Empfang alle Zweig-Pushs ablehnt, die den aktuellen Tipp für testing enthalten, wenn etwas vorhanden ist, es sei denn, der Push ist für testing selbst oder für master. Es ist fast so einfach, das zu tun, als es zu sagen:

testtip=`git rev-parse testing`
[[ `git merge-base testing master` = $testtip ]] && exit 0    # okay if testing's merged

while read old new ref; do
        [[ $ref = refs/heads/* ]] || continue      # only care about branches
        [[ $new = *[^0]* ]] || continue            # not checking branch deletions
        [[ $ref = */master ]] && continue          # not checking pushes to master
        [[ $ref = */testing ]] && continue         # nor testing


        range=$new; [[ $old = *[^0]* ]] && range=$old..$new

        [[ `git rev-list --first-parent $range` != *$testtip* ]] \
        && [[ `git rev-list $range` = *$testtip* ]] \
        && {
                echo Push to $ref merges from unmerged testing commits, rejecting Push
                exit 1
        }
done

edit: whoops, es lehnte alles ab, was auf dem Testen beruhte, nicht nur alles, was es zusammenführte. Fest.

2
jthill