Git kancalarını depoya koymak


198

Kötü bir uygulama olarak mı görülüyor - .git/hooksproje havuzuna koymak (örneğin sembolik bağlantıları kullanarak). Evetse, aynı kancaları farklı git kullanıcılarına ulaştırmanın en iyi yolu nedir?

Yanıtlar:


143

Genellikle Scytale ile birkaç ek öneriyle, ayrı bir cevaba değecek kadar katılıyorum.

İlk olarak, özellikle bu kancalar politikayı uygulamak veya faydalı bildirimler oluşturmakla ilgili ise, uygun sembolik bağlantıları oluşturan bir komut dosyası yazmalısınız. İnsanların, sadece bin/create-hook-symlinkskendileri yapmak zorunda olduklarından daha fazla yazabilecekleri zaman kancaları kullanma olasılıkları daha yüksek olacaktır .

İkincisi, doğrudan symlinking kancaları kullanıcıların kendi kişisel kancalarını eklemelerini önler. Örneğin, herhangi bir boşluk hatası olmadığından emin olan örnek ön işleme kancasını seviyorum. Bunun için harika bir yol, repodaki bir kanca sarma betiğine düşmek ve tüm kancaları ona bağlamaktır. Sarıcı daha sonra hangi kancaya çağrıldığını anlamak için $0bir bash betiği; argv[0]aksi gibi bir eşdeğer olduğu varsayılarak) inceleyebilir , daha sonra repo içinde uygun kancayı ve yeniden adlandırılması gereken uygun kullanıcının kancasını çağırabilir. , tüm argümanları her birine geçirerek. Bellekten hızlı örnek:

#!/bin/bash
if [ -x $0.local ]; then
    $0.local "$@" || exit $?
fi
if [ -x tracked_hooks/$(basename $0) ]; then
    tracked_hooks/$(basename $0) "$@" || exit $?
fi

Yükleme komut dosyası, önceden varolan tüm kancaları yana taşır ( .localadlarına ekler ) ve bilinen tüm kanca adlarını yukarıdaki komut dosyasına bağlar:

#!/bin/bash
HOOK_NAMES="applypatch-msg pre-applypatch post-applypatch pre-commit prepare-commit-msg commit-msg post-commit pre-rebase post-checkout post-merge pre-receive update post-receive post-update pre-auto-gc"
# assuming the script is in a bin directory, one level into the repo
HOOK_DIR=$(git rev-parse --show-toplevel)/.git/hooks

for hook in $HOOK_NAMES; do
    # If the hook already exists, is executable, and is not a symlink
    if [ ! -h $HOOK_DIR/$hook -a -x $HOOK_DIR/$hook ]; then
        mv $HOOK_DIR/$hook $HOOK_DIR/$hook.local
    fi
    # create the symlink, overwriting the file if it exists
    # probably the only way this would happen is if you're using an old version of git
    # -- back when the sample hooks were not executable, instead of being named ____.sample
    ln -s -f ../../bin/hooks-wrapper $HOOK_DIR/$hook
done

6
Eklediğim chmod +x .git/hooks/*adresinden Müşteri bin/create-hook-symlinks bunu çalışmak.
guneysus

6
@guneysus Buna gerek yok, çünkü kancalar zaten çalıştırılabilir olmalıdır (bu şekilde kontrol edilmelidir) ve bağlantıların özel izinlere ihtiyacı yoktur, sadece bağlandıkları dosyalar.
Cascabel

13
Kanca dir almak için daha iyi bir yoludur HOOK_DIR=$(git rev-parse --show-toplevel)/.git/hooks.
Arnold Daniels


6

111

Hayır, onları depoya koymak iyidir, hatta bunu yapmanızı öneririm (başkaları için de faydalıysa). Kullanıcı, bir yandan biraz acı veren, ancak diğer yandan kullanıcıları rızası olmadan rastgele kod çalıştırmalarına karşı koruyan (örneğin, symlinking yoluyla) açık bir şekilde etkinleştirmelidir.


13
ya bir şirket politikası şey ise, kod "keyfi" değil bu gerekli kod, bu nedenle bu GIT, izlenen başka bir (önceden tanımlanmış) dizine sahip olmadığı için bir sınırlama olarak kabul edilir. kancalarla birlikte idam edildi
Tobias Hagenbeek

14
Kancaları otomatik olarak teslim etmek bir güvenlik sorunudur, Git'in doğrudan yapmadığına sevindim - ekip / şirket politikasını uygulamak, sunucu tarafında kancaları kullanmak veya kullanıcıların bunları scy açıkladığı gibi manuel olarak etkinleştirmeye karar vermesine izin vermek :)
Mark K Cowan

4
"kullanıcıları [...] kendi rızaları olmadan rastgele kod çalıştırmalarına karşı korur". Bir geliştirici (symlinking) önermek istiyorsa, kanca başka biri tarafından değiştirilebilir ve "rızaları olmadan rastgele kod" çalıştırabilir
MiniGod

24
MiniGod: Tabii ki. Yeterince paranoyaksanız, kancaları işaretlemek yerine kopyalayabilir, sonra denetleyebilir ve yalnızca etkinleştirebilirsiniz. Bununla birlikte, çoğu (alıntı gerekli) Git depoları, kullanıcının makinesinde çalıştırılacak kaynak kodunu içerecektir, bu nedenle yine de sürekli değişen, denetlenmemiş kodu çalıştırmanız muhtemeldir. Ama evet, bir anlamı var. ;)
scy

47

Günümüzde, sürüm kontrolü altındaki bir dizini git hooks dizininiz olarak ayarlamak için aşağıdakileri yapabilirsiniz, örn MY_REPO_DIR/.githooks.

git config --local core.hooksPath .githooks/

Yine de doğrudan uygulanamaz, ancak README'nize (veya her neyse) bir not eklerseniz, bu her geliştirici için minimum çaba gerektirir.


3
Viget.com/articles/two-ways-to-share-git-hooks-with-your-team üzerinde bulduğum bir numara seçeneği Makefile / CMake yapılandırmanızdan / herhangi bir şeyden ayarlamaktır.
Julius Bullinger

6

Gönderen http://git-scm.com/docs/git-init#_template_directory , sen / her yeni oluşturulan git repo ait dir kanca .git güncellemek için bu mekanizmalardan birini kullanabilirsiniz:

Şablon dizini, oluşturulduktan sonra $ GIT_DIR klasörüne kopyalanacak dosyalar ve dizinler içerir.

Şablon dizini aşağıdakilerden biri olacaktır (sırayla):

  • --template seçeneği ile verilen argüman;

  • $ GIT_TEMPLATE_DIR ortam değişkeninin içeriği;

  • init.templateDir yapılandırma değişkeni; veya

  • varsayılan şablon dizini: / usr / share / git-core / templates.


5

Projede saklayın ve yapıya kurun

Diğerleri yanıtlarında belirtildiği gibi, kancalarınız belirli projeleriniz için spesifikse, git tarafından yönetilen projenin kendisine ekleyin. Bunu daha da ileri götürürdüm ve projenizin tek bir komut dosyası veya komut kullanarak derlenmesinin iyi bir uygulama olduğu göz önüne alındığında, kancaların derleme sırasında yüklenmesi gerektiğini söyleyebilirim.

Biraz daha derinlemesine okumak istiyorsanız, git kancalarını yönetme hakkında bir makale yazdım .

Java ve Maven

Tam sorumluluk reddi; Aşağıda açıklanan Maven eklentisini yazdım.

Java projeleriniz için Maven ile derleme yönetimini yönetiyorsanız, aşağıdaki Maven eklentisi projenizdeki bir konumdan kanca takmayı işler.

https://github.com/rudikershaw/git-build-hook

Tüm Git kancalarınızı projenizdeki bir dizine koyun, ardından pom.xmlaşağıdaki eklenti bildirimini, hedefini ve yapılandırmasını içerecek şekilde yapılandırın.

<build>
  <plugins>
    <plugin>
      <groupId>com.rudikershaw.gitbuildhook</groupId>
      <artifactId>git-build-hook-maven-plugin</artifactId>
      <configuration>
        <gitConfig>
          <!-- The location of the directory you are using to store the Git hooks in your project. -->
          <core.hooksPath>hooks-directory/</core.hooksPath>
        </gitConfig>
      </configuration>
      <executions>
        <execution>
          <goals>       
            <!-- Sets git config specified under configuration > gitConfig. -->
            <goal>configure</goal>
          </goals>
        </execution>
      </executions>
    </plugin>
      <!-- ... etc ... -->
  </plugins>
</build>

Proje derlemenizi çalıştırdığınızda, eklenti git'i belirtilen dizinden kancaları çalıştıracak şekilde yapılandırır. Bu, projenizde çalışan herkes için bu dizindeki kancaları etkin bir şekilde ayarlayacaktır.

JavaScript ve NPM

NPM için Husky adında bir bağımlılık vardır, bu da JavaScript'te yazılmış kancalar da dahil olmak üzere kancaları takmanıza izin verir.

// package.json
{
  "husky": {
    "hooks": {
      "pre-commit": "npm test",
      "pre-push": "npm test",
      "...": "..."
    }
  }
}

Diğerleri

Ayrıca, orada olup önceden taahhüt Python projeler için Overcommit Yakut projeleri için ve Lefthook yakut için veya Düğüm projelerine.


1
Bu eklentiyi oluşturduğunuz için teşekkürler, ön işleme dosyamı entegre etmeyi çok kolay hale getirdi.
Michiel Bugher


1

İşte, depoda normal bir dosya olarak gönderebileceğiniz ve git kancasını kod dosyasına eklemek için çalıştırılabilen add-git-hook.sh adlı bir komut dosyası. Hangi kancayı kullanacağınızı (ön işlem, son işlem sonrası, ön itme, vb.) Ve kedi heredocundaki kancanın tanımını ayarlayın.

#!/usr/bin/bash
# Adds the git-hook described below. Appends to the hook file
# if it already exists or creates the file if it does not.
# Note: CWD must be inside target repository

HOOK_DIR=$(git rev-parse --show-toplevel)/.git/hooks
HOOK_FILE="$HOOK_DIR"/post-commit

# Create script file if doesn't exist
if [ ! -e "$HOOK_FILE" ] ; then
        echo '#!/usr/bin/bash' >> "$HOOK_FILE"
        chmod 700 "$HOOK_FILE"
fi

# Append hook code into script
cat >> "$HOOK_FILE" <<EOF

########################################
# ... post-commit hook script here ... #
########################################

EOF

Bu komut dosyasının yürütülebilir izinlere sahip olması anlamlı olabilir veya kullanıcı doğrudan çalıştırabilir. Bunu yaptıktan sonra diğer makinelere otomatik olarak git-pull yapmak için kullandım.

DÜZENLEME-- OP sorusu olmayan ve OP'nin aradığı kolay olmayan soruyu cevapladım. Aşağıdaki yorumlarda onları harici olarak yönetmeye karşı repoda kanca komut dosyaları göndermeye yönelik kullanım durumlarını ve argümanları seçtim. Umarım aradığınız şey buydu.


Çabalarınızı takdir ediyorum ve burada değerli bir bilgi olduğuna inanıyorum - belirtilen soruya cevap vermiyor.
shabunc

Kanımca, kancalar belirli bir veri havuzuna özgü veya kullanılan iş akışlarının ayrılmaz bileşenleri ise, veri havuzuna dosya olarak aittirler. Çözdüğünden daha fazla sorun yaratmadan onları başka bir yere koymak zor. Genel kancaları kendi deposunda veya proje deposunu gıcırdayarak temiz tutan ancak daha az pratik olma pahasına paylaşılan bir sürücüde saklayabilirsiniz. Kancaların eklenmesinin kolay olması gerektiğini söyleyen diğer kullanıcılara katılıyorum. Sembolik bağlantılar, belirli bir sisteme veya dosya yapısına gereksiz bağımlılık yaratabilir.
mathewguest

Ayrıca, sembolik bağlantılar kullanıcıların kendi kancalarını ekleme yeteneğini bozar. .Git / hooks dizini izlenmez, bu nedenle kaynak depoda başlamalı ve başka türlü değil, kancalar komut dosyasına girmelidir. Bence karşı argüman git kancalarının proje yerine iş akışı veya ekiple daha fazla ilişkili olması ve bu nedenle depoya ait olmamasıdır. Özel kullanım durumunuza bağlı olarak, git deposunu daha az ilgili kancalarla potansiyel olarak kirletme konusunda daha iyi misiniz yoksa bunları başka bir yere koymada bir sürü karmaşıklıktan vazgeçmeyi tercih eder misiniz?
mathewguest

1

Composer tabanlı PHP projeleri için mühendislere otomatik olarak dağıtabilirsiniz. İşte ön taahhüt ve kesin msj kancalarına bir örnek.

Bir hooksklasör oluşturun , ardından composer.json'unuzda:

 },
 "scripts": {
     "post-install-cmd": [
         "cp -r 'hooks/' '.git/hooks/'",
         "php -r \"copy('hooks/pre-commit', '.git/hooks/pre-commit');\"",
         "php -r \"copy('hooks/commit-msg', '.git/hooks/commit-msg');\"",
         "php -r \"chmod('.git/hooks/pre-commit', 0777);\"",
         "php -r \"chmod('.git/hooks/commit-msg', 0777);\"",
     ],

Daha sonra, herkes composer installdüzenli olarak çalışırken proje devam ettikçe bunları güncelleyebilirsiniz .


0

Ön işleme gibi ön işleme kanca yönetimi için yönetilen bir çözüm kullanabilirsiniz . Veya Datree.io gibi sunucu tarafı git-kancaları için merkezi bir çözüm . Şu gibi yerleşik politikalara sahiptir:

  1. Sırları tespit edin ve birleştirin .
  2. Uygun Git kullanıcı yapılandırmasını zorunlu kılın .
  3. Jira bilet entegrasyonunu zorunlu kıl - çekme isteği adı / taahhüt mesajında ​​bilet numarasını belirt .

Tüm kancalarınızın yerini almayacak, ancak kancaları her geliştiricinin bilgisayarına / repo'suna yapılandırma cehennemi olmadan geliştiricilerinize en belirgin olanlarla yardımcı olabilir.

Feragatname: Datrees kurucularından biriyim


3
Bence ilginç bir ürün yapıyorsunuz ama bunun soruya cevap vermediğini ve temelde bir öz-tanıtım olduğunu ve başka bir şey olmadığını düşünüyorum.
shabunc
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.