3 पॉइंट द्वारा GN⁺ 2024-11-26 | 1 टिप्पणियां | WhatsApp पर शेयर करें
  • ऐसे environment में जहाँ personal और work repositories दोनों ~/workspace में रखे जाते हैं, folder location के बजाय remote URL के आधार पर Git identity को अलग करना ज़्यादा सटीक होता है
  • Git का includeIf gitdir के ज़रिए path-based settings लोड कर सकता है, लेकिन जब एक ही working directory में कई accounts की repositories मिली-जुली हों, तो path-based branching की सीमा सामने आ जाती है
  • hasconfig:remote.*.url: condition इस्तेमाल करने पर GitHub, GitLab, SourceHut या किसी खास GitHub organization जैसे remote URL pattern के हिसाब से अलग config files include की जा सकती हैं
  • SSH keys को ~/.ssh/config में Host, Hostname, User, IdentityFile के साथ अलग से manage करना चाहिए, और उसी github.com पर भी organization-specific keys इस्तेमाल करनी हों तो Host alias की जरूरत होती है
  • url.<base>.insteadOf को साथ में set करने पर आप रोज़मर्रा की तरह git@github.com:orgname/project इस्तेमाल कर सकते हैं, लेकिन internally यह gh-work:orgname में replace होकर सही SSH setting से होकर जाता है

remote URL के आधार पर Git settings अलग करना

  • मौजूदा includeIf examples gitdir:~/code/**, gitdir:~/work/** की तरह local directory path के अनुसार अलग config files include करते हैं
    • ~/code के नीचे ~/.config/git/personal, और ~/work के नीचे ~/.config/git/work लोड किया जा सकता है
    • include की गई files में आम तौर पर Git identity और signing key जैसे user.name, user.email, user.signingkey होते हैं
  • अगर सारा code ~/workspace के नीचे रखा जाए, तो personal, work-1, work-2 repositories एक ही path structure में मिल सकती हैं, इसलिए सिर्फ path-based conditions से मनचाहा अलगाव करना मुश्किल हो जाता है
  • Git का hasconfig:remote.*.url: इस्तेमाल करने पर current repository में कोई खास remote URL होने पर ही config file include की जा सकती है
    • git@github.com:*/** से match हो तो ~/.config/git/config-gh
    • git@github.com:orgname/** से match हो तो ~/.config/git/config-gh-org
    • git@gitlab.com:*/** से match हो तो ~/.config/git/config-gl
    • git@git.sr.ht:*/** से match हो तो ~/.config/git/config-srht
  • Git आख़िरी matched setting को include करता है, इसलिए condition order महत्वपूर्ण है
    • github.com:orgname/** condition को general github.com:*/** condition से नीचे होना चाहिए, ताकि organization-specific setting general GitHub setting से overwrite न हो
  • नतीजतन, जिन repositories में github.com:orgname/** remote है वे config-gh-org इस्तेमाल करती हैं, और बाकी GitHub repositories general GitHub setting इस्तेमाल करती हैं

SSH keys और insteadOf से organization-specific access information मिलाना

  • Git identity से अलग, remote पर pull·push करने के लिए SSH key settings की जरूरत होती है
    • ~/.ssh/config में gitlab.com के लिए ~/.ssh/gitlab.id_ed25519
    • github.com के लिए ~/.ssh/github.id_ed25519 की तरह IdentityFile specify किया जा सकता है
  • ssh-agent settings के हिसाब से हर Host के IdentityFile के नीचे IdentitiesOnly yes जोड़ना अच्छा हो सकता है
  • एक ही Hostname यानी github.com पर organization के हिसाब से अलग keys इस्तेमाल करनी हों, तो Host value अलग रखनी होगी
    • configuration Host gh-work, Hostname github.com, User git, IdentityFile ~/.ssh/work.id_ed25519 के रूप में होती है
  • Git settings में url "gh-work:orgname" और insteadOf = git@github.com:orgname इस्तेमाल करने पर Git URL अपने-आप replace किया जा सकता है
    • user git clone git@github.com:orgname/project की तरह input देता है
    • Git github.com:orgname हिस्से को gh-work:orgname में बदलकर ~/.ssh/config की gh-work setting इस्तेमाल करता है
  • यह तरीका SSH and multiple Git credentials से लिया गया trick है, और साथ में reference किए गए लेख ये हैं

1 टिप्पणियां

 
GN⁺ 2024-11-26
Hacker News की राय
  • insteadOf के बजाय repository को gh-work:org/repo के रूप में clone करें, और Git config में includeIf "hasconfig:remote.*.url:gh-work:**/**" रखें
    ऐसा करने पर gh-work के तहत परिभाषित SSH identity से clone की गई repositories अपने-आप gh-work.inc config ले लेंगी, और उसमें Git identity तथा SSH config जैसी signing key शामिल होगी
    आखिरकार gh-work नाम ही SSH identity और Git identity को अलग करने का आधार बन जाता है, इसलिए यह समझना आसान है

    • लेख का समाधान जरूरत से ज्यादा flexibility वाला लग रहा था और थोड़ा असहज कर रहा था, लेकिन runtime parameter को एक तक घटाने का यह elegant तरीका लगता है
    • includeIf case-sensitive है, और priority में आखिरी config जीतती है
      यह सही चल रहा है या नहीं देखने के लिए git remote get-url origin और git config --get user.email चलाया जा सकता है
    • इस तरीके से वे scripts टूट सकती थीं जो remote repository URL के किसी खास format की उम्मीद करती हैं
  • मेरे हिसाब से बेहतर तरीका है कि HOME की .gitconfig में identity-specific aliases रखें, और repository initialize या clone करने के तुरंत बाद git config-company या git config-personal चलाएँ
    user.useConfigOnly = true चालू करके, alias में local repository के user.email, user.name, core.sshCommand को क्रमशः personal/work SSH keys पर set कर दें

    • सवाल यह है कि शुरुआत में सही SSH settings के बिना initial clone कैसे किया जाए
      लेख के तरीके का फायदा यह लगता है कि organization से clone करने पर यह सीधे काम करता है
  • पहले एक startup में कोई व्यक्ति रोज़ किसी परीकथा जैसे मनमाने नाम से अपनी identity बदलता था
    सोमवार के commits Mr. Bunnymann, मंगलवार के commits Doctor Funtime जैसे होते थे, इसलिए version control forensics करते समय बहुत परेशानी होती थी
    नरमी से देखें तो शायद वह यह याद दिलाना चाहता था कि कोई भी identity setting में कुछ भी डाल सकता है, इसलिए उस value पर बहुत भरोसा नहीं करना चाहिए

    • अगर blameless culture हो, तो version control forensics में किसने किया से ज्यादा महत्वपूर्ण यह होता कि कब हुआ और किन changes के आसपास हुआ
      फिर भी details पूछने या style और expertise का अंदाजा लगाने के लिए यह जानना मददगार होता है कि किसने किया
      commits पर GPG signature अनिवार्य करके और allowed GPG identities register करके author/committer metadata के बजाय signature से वास्तविक author पहचाना जा सकता है
      बेशक “simple” और GPG signature हमेशा साथ-साथ अच्छे से नहीं चलते
    • इसे उतना ही trust करें जितना किसी employee द्वारा लिखे document या signature को करते हैं
      अगर आप यह भरोसा नहीं कर सकते कि employee अपने commits को सही तरह identify करेगा, तो मेरे हिसाब से उसे निकाल देना चाहिए
    • नरमी से देखें तो, उत्सुकता है कि क्या वही signing key इस्तेमाल की गई थी
    • हैरानी है कि ऐसी शरारत के लिए उसे पैसे मिले
    • Git में author और committer को अलग करने का built-in support है, और शायद उसने केवल author attribute बदला था
  • ~/.ssh/config छेड़ने की जरूरत नहीं; ~/.gitconfig या लेख की तरह ~/.config/git/personal में core.sshCommand = /usr/bin/ssh -o IdentitiesOnly=yes -i ~/.ssh/IdentityFile2 -a डाल दें
    इससे insteadOf के बिना भी submodules आसान हो जाते हैं

    • अगर एक से ज्यादा SSH identities हों तो क्या करें, यह सवाल बचता है
  • मैं काफी समय से directory-based includeIf इस्तेमाल कर रहा था (https://www.bobek.cz/til/git-identities/), लेकिन hasconfig:remote वाकई बहुत साफ-सुथरा है
    यह repository clone करते समय भी काम करता है

  • includeIf काफी अच्छा है
    फिलहाल SSH complexity को ~/.ssh में रखता हूँ, और हर customer/project/identity के लिए एक-एक include रखता हूँ
    GitHub जैसी जगहों के लिए, जहाँ unique hostname नहीं होता, customer-github जैसा host alias लगाता हूँ, और HostName github.com, IdentityFile ~/.ssh/customer_rsa, User git की तरह config करता हूँ
    इसके बाद git clone में बस वही alias इस्तेमाल करना होता है

    • कई GitHub SSH identities manage करने के लिए मैंने 12 साल पहले एक tool बनाया था और अभी भी maintain कर रहा हूँ: https://github.com/dolmen/github-keygen
  • मुझे भी यही समस्या थी, और अब लगता है समाधान मिल गया
    NixOS और home-manager को Linux और Mac पर इस्तेमाल करने से यह setup आसान हो जाता है
    programs.git.includes में condition = "hasconfig:remote.*.url:git@github.com:/**" और user.email setting डाल दें
    संदर्भ: https://nix-community.github.io/home-manager/options.xhtml#opt-programs.git.includes

    • सीधे .gitconfig में लिखने से यह कम आसान लगता है
      condition और setting तो लेख जैसी ही हैं, लेकिन इसमें build/template step और अजीब syntax वाली नई programming language सीखना भी जुड़ जाता है
  • मैं पहले से includeIf: "gitdir" से काम और personal settings अलग कर रहा था, लेकिन hasconfig:remote पूरी तरह game changer है

    • यकीन नहीं होता कि यह खजाना 3 साल तक draft के रूप में छिपा रहा
  • consultants को मैं हमेशा strongly recommend करता हूँ कि काम के लिए अलग machine इस्तेमाल करें, या कम-से-कम अलग OS user रखें
    personal machine को काम में इस्तेमाल करने से बड़ी मुश्किल में पड़ने का risk होता है

    • “personal machine को काम में इस्तेमाल करना” बहुत व्यापक scope वाला वाक्य है
      remote-first company में खुद laptop arrange करना और हर 2–3 साल में नई device खरीदने का खर्च मिलना, लेकिन फिर भी वह personal laptop होना—ऐसा भी हो सकता है, या आप temporary contractor भी हो सकते हैं
      किस situation में और क्यों समस्या होती है, इसे ज्यादा specific बताना चाहिए
      risk सचमुच है, लेकिन अगर उसे list नहीं कर पा रहे, तो यह education से ज्यादा FUD फैलाने जैसा हो जाता है
  • project के हिसाब से Git identity आसानी से बदलने के लिए बनाया गया tool: https://github.com/cquintana92/git-switch-user
    identities set करने के बाद $ git su Personal या $ git su Work चलाने पर email, name, SSH key, और optional रूप से PGP key तक repository की .git/config में set हो जाती है
    इससे काफी समय बचा

    • SSH के जरिए Git access के लिए GitHub identity management tool भी है: https://github.com/dolmen/github-keygen
      12 साल पुराना tool है, लेकिन अभी भी actively maintained है