"यदि कोई कर्मचारी अपना काम अच्छी तरह से करना चाहता है, तो उसे पहले अपने औजारों को तेज करना होगा।" - कन्फ्यूशियस, "द एनालेक्ट्स ऑफ कन्फ्यूशियस। लू लिंगगोंग"
मुखपृष्ठ > प्रोग्रामिंग > स्क्रिप्टिंग का उपयोग करते हुए सुपरपावर गिट उपनाम

स्क्रिप्टिंग का उपयोग करते हुए सुपरपावर गिट उपनाम

2024-11-08 को प्रकाशित
ब्राउज़ करें:108

Superpowered Git Aliases using Scripting

Git उपनाम क्या हैं?

गिट उपनाम शेल में नियमित उपनाम के समान काम करते हैं, लेकिन वे गिट कमांड के लिए विशिष्ट हैं। वे आपको लंबे कमांड के लिए शॉर्टकट बनाने या नए कमांड बनाने की अनुमति देते हैं जो डिफ़ॉल्ट रूप से उपलब्ध नहीं हैं।

उपनाम अन्य गिट कमांड के समान शेल वातावरण में चलते हैं, और अधिकतर सामान्य वर्कफ़्लो को सरल बनाने के लिए उपयोग किए जाते हैं।

सरल उपनाम

सरल उपनाम तर्कों के एक सेट के साथ एकल Git कमांड को कॉल करते हैं। उदाहरण के लिए, आप s उपनाम के साथ git status चलाकर रिपॉजिटरी की स्थिति दिखाने के लिए एक उपनाम बना सकते हैं:

[alias]
  s = status

फिर आप रिपॉजिटरी की स्थिति दिखाने के लिए git s चला सकते हैं। चूँकि हमने उपनाम को ~/.gitconfig में कॉन्फ़िगर किया है, यह सिस्टम पर सभी रिपॉजिटरी के लिए उपलब्ध है।

अधिक जटिल उपनाम

आप गिट उपनाम भी बना सकते हैं जो एक मनमाना शेल कमांड चलाते हैं। ऐसा करने के लिए, उपनाम को ! से शुरू करना होगा। यह git को उपनाम निष्पादित करने के लिए कहता है जैसे कि यह git उपकमांड नहीं था। उदाहरण के लिए, यदि आप क्रम में दो गिट कमांड चलाना चाहते हैं, तो आप एक उपनाम बना सकते हैं जो शेल कमांड चलाता है:

[alias]
  my-alias = !git fetch && git rebase origin/master

जब आप git my-alias चलाते हैं तो यह उपनाम git Fetch और git rebase origin/main क्रम में चलता है।

गिट उपनामों की एक सीमा यह है कि उन्हें मल्टीलाइन मान पर सेट नहीं किया जा सकता है। इसका मतलब है कि अधिक जटिल उपनामों के लिए आपको उन्हें छोटा करना होगा।

इसके अतिरिक्त, एक INI फ़ाइल में एक ; शेष पंक्ति पर टिप्पणी करने के लिए वर्ण का उपयोग किया जाता है। इसका मतलब है कि आप इसका उपयोग नहीं कर सकते; आपके उपनाम आदेशों में।

ये दो सीमाएं मानक गिट उपनाम सिंटैक्स का उपयोग करके अधिक जटिल उपनाम बनाना मुश्किल बना सकती हैं, लेकिन यह अभी भी किया जा सकता है। उदाहरण के लिए, यदि शाखा का उपयोग करने वाला उपनाम इस तरह दिख सकता है:

[alias]
  branch-if = !bash -c "'!f() { if [ -z \"$1\" ]; then echo \"Usage: git branch-if \"; else git checkout -b $1; fi; }; f'"

ये सीमाएँ उन उपनामों को बनाने और बनाए रखने को और अधिक जटिल बनाती हैं जिनके भीतर किसी भी प्रकार का नियंत्रण प्रवाह होता है। यहीं पर स्क्रिप्टिंग आती है।

स्क्रिप्ट के साथ उपनाम स्थापित करना

आप अपनी पसंद की किसी भी प्रोग्रामिंग भाषा का उपयोग करके गिटालिया को स्क्रिप्ट कर सकते हैं। यदि आप बैश स्क्रिप्टिंग से परिचित हैं और इसका उपयोग करना चाहते हैं, तो आप एक बैश स्क्रिप्ट बना सकते हैं जो वांछित गिट कमांड चलाती है। सच तो यह है कि मैं जावास्क्रिप्ट में बहुत मजबूत हूं, इसलिए मैं इसका उपयोग करूंगा।

एक अन्य प्रमुख लाभ यह है कि स्क्रिप्टिंग भाषा का उपयोग करके, आपके उपनाम तर्कों को ले सकते हैं और उन पर काम कर सकते हैं बहुत अधिक आसानी से। Git आपके द्वारा CLI पर दिए गए किसी भी तर्क को आपके आदेश के अंत में जोड़कर आपके उपनाम में अग्रेषित कर देगा। इस प्रकार, आपकी स्क्रिप्ट उन्हें बिना किसी समस्या के पढ़ने में सक्षम होनी चाहिए। उदाहरण के लिए, नोड जेएस में आप स्क्रिप्ट में दिए गए तर्कों को सीधे प्रक्रिया.argv पर एक्सेस कर सकते हैं।

इसे सेट करने के बुनियादी चरण चुनी गई भाषा के आधार पर नहीं बदलते हैं। आपको इसकी आवश्यकता होगी:

  • एक स्क्रिप्ट बनाएं जो वांछित गिट कमांड चलाती है
  • एक उपनाम लिखें जो स्क्रिप्ट चलाता है

केस स्टडी: रीबेस मेन/मास्टर

हाल के वर्षों में नई रिपॉजिटरी के लिए डिफ़ॉल्ट शाखा का नाम मास्टर से मुख्य में बदल गया है। इसका मतलब यह है कि जब आप किसी नए रिपॉजिटरी को क्लोन करते हैं, तो डिफ़ॉल्ट शाखा मास्टर के बजाय मुख्य हो सकती है। अब कोई सुपर कंसिस्टेंट नाम नहीं है, क्योंकि पारिस्थितिकी तंत्र संक्रमण में है। यह कुल मिलाकर एक अच्छी बात है, लेकिन इसका मतलब यह है कि रिबेस के लिए ऊपर दिया गया हमारा उपनाम सभी मामलों में काम नहीं करेगा।

हमें यह जांचने के लिए अपना उपनाम अपडेट करना होगा कि शाखा मुख्य है या मास्टर और फिर सही शाखा को फिर से आधार बनाना होगा। यह किसी स्क्रिप्ट के लिए एक आदर्श उपयोग का मामला है।

#!/usr/bin/env node

const { execSync } = require('child_process');

// We want to run some commands and not immediately fail if they fail
function tryExec(command) {
  try {
    return {
      status: 0
      stdout: execSync(command);
    }
  } catch (error) {
    return {
      status: error.status,
      stdout: error.stdout,
      stderr: error.stderr,
    }
  }
}

function getOriginRemoteName() {
  const { stdout, code } = tryExec("git remote", true);
  if (code !== 0) {
    throw new Error("Failed to get remote name. \n"   stdout);
  }
  // If there is an upstream remote, use that, otherwise use origin
  return stdout.includes("upstream") ? "upstream" : "origin";
}

// --verify returns code 0 if the branch exists, 1 if it does not
const hasMain = tryExec('git show-ref --verify refs/heads/main').status === 0;

// If main is present, we want to rebase main, otherwise rebase master
const branch = hasMain ? 'main' : 'master';

const remote = getOriginRemoteName()

// Updates the local branch with the latest changes from the remote
execSync(`git fetch ${remote} ${branch}`, {stdio: 'inherit'});
// Rebases the current branch on top of the remote branch
execSync(`git rebase ${remote}/${branch}`, {stdio: 'inherit'});

वर्तमान में, स्क्रिप्ट को चलाने के लिए हमें नोड ~/gitaliases/git-rebase-main.js चलाने की आवश्यकता होगी। यह आदर्श नहीं है, और ऐसा कुछ नहीं है जिसे करने की आपको कभी आदत हो। हम स्क्रिप्ट को चलाने वाला एक गिट उपनाम बनाकर इसे आसान बना सकते हैं।

[alias]
  rebase-main = !node ~/gitaliases/git-rebase-main.js

अब आप सही शाखा को रीबेस करने के लिए git rebase-main चला सकते हैं, भले ही वह मुख्य हो या मास्टर।

केस स्टडी: संशोधन करें

एक और उपनाम जो मैंने अपनी सभी मशीनों पर स्थापित किया है वह है अंतिम प्रतिबद्धता में संशोधन करना। यह मेरे लिए एक अत्यंत सामान्य वर्कफ़्लो है, और मैं इसे एकल कमांड के रूप में रखना पसंद करता हूँ। यह स्क्रिप्ट के लिए एक बढ़िया उपयोग का मामला है, क्योंकि यह एक सरल कमांड है जिसे मैं अक्सर चलाना चाहता हूं।

#!/usr/bin/env node

// Usage: git amend [undo]
const tryExec = require('./utils/try-exec');

async function getBranchesPointingAtHead() {
  const { stdout, code } = await tryExec('git branch --points-at HEAD', true);
  if (code !== 0) {
    throw new Error('Failed to get branches pointing at HEAD. \n'   stdout);
  }
  return stdout.split('\n').filter(Boolean);
}

(async () => {
  const branches = await getBranchesPointingAtHead();
  if (branches.length !== 1) {
    console.log(
      'Current commit is relied on by other branches, avoid amending it.'
    );
    process.exit(1);
  }
  if (process.argv[2] === 'undo') {
    await tryExec('git reset --soft HEAD@{1}');
  } else {
    await tryExec('git commit --amend --no-edit');
  }
})();

यह स्क्रिप्ट पिछली स्क्रिप्ट की तुलना में थोड़ी अधिक जटिल है, क्योंकि इसमें कुछ नियंत्रण प्रवाह है। यह जांच करेगा कि क्या वर्तमान प्रतिबद्धता अन्य शाखाओं पर निर्भर है, और यदि ऐसा है तो यह एक त्रुटि के साथ बाहर निकल जाएगा। यह आपको उस कमिट में संशोधन करने से रोकने के लिए है जिस पर अन्य शाखाएँ भरोसा करती हैं, क्योंकि ऐसा करने से कमिट पर निर्भर किसी भी शाखा को मर्ज करने का प्रयास करते समय समस्याएँ पैदा होंगी।

उपनाम सेट करने के लिए, आप पहले की तरह ही विधि का उपयोग कर सकते हैं:

[alias]
  amend = !node ~/gitaliases/git-amend.js

अब आप अंतिम कमिट को संशोधित करने के लिए git amend चला सकते हैं, या अंतिम संशोधन को पूर्ववत करने के लिए git amend undo चला सकते हैं। यह एक स्क्रिप्ट है जिसे मैंने शुरू में अपने gitconfig में इनलाइन लिखा था, लेकिन जैसे-जैसे इसकी जटिलता बढ़ती गई, मैंने इसे एक स्क्रिप्ट फ़ाइल में स्थानांतरित कर दिया। यह आपके उपनामों में जटिलता को प्रबंधित करने का एक शानदार तरीका है। तुलना के लिए, यहां मूल उपनाम है:

[alias]
  amend = !bash -c "'f() { if [ $(git branch --points-at HEAD | wc -l) != 1 ]; then echo Current commit is relied on by other branches, avoid amending it.; exit 1; fi; if [ \"$0\" = "undo" ]; then git reset --soft \"HEAD@{1}\"; else git commit --amend --no-edit; fi }; f'"

इस स्क्रिप्ट को .sh फ़ाइल में भी निकाला जा सकता था, लेकिन चीजों को नोड में रखने से मेरे लिए व्यक्तिगत रूप से रखरखाव का बोझ कम हो जाता है। अतीत में, जब भी मुझे इस उपनाम को अद्यतन करने की आवश्यकता होती थी तो मुझे इसे बैश लिंटर में पेस्ट करना पड़ता था, अपने परिवर्तन करने पड़ते थे, इसे छोटा करना पड़ता था और फिर इसे वापस अपने gitconfig में पेस्ट करना पड़ता था। यह एक पीड़ा थी, और मैं अक्सर इसके कारण उपनाम अपडेट करने से बचता था। अब चूँकि यह एक स्क्रिप्ट फ़ाइल में है, मैं इसे किसी भी अन्य स्क्रिप्ट की तरह अपडेट कर सकता हूँ।

कुछ चेतावनी

उपनामों को स्क्रिप्ट के रूप में सेट करने से आपके गिट उपनामों में शक्ति का एक नया स्तर अनलॉक हो सकता है। हालाँकि, ऐसा करते समय कुछ बातों का ध्यान रखना चाहिए।

इस तरह के उपनाम सेट करते समय, यह याद रखना महत्वपूर्ण है कि स्क्रिप्ट की सीडब्ल्यूडी स्क्रिप्ट को चलाने वाले शेल की वर्तमान कार्यशील निर्देशिका होगी। स्क्रिप्ट में किसी भी संबंधित फ़ाइल पथ को शेल के cwd के सापेक्ष माना जाएगा, स्क्रिप्ट के स्थान के रूप में नहीं। यह कभी-कभी अत्यधिक उपयोगी होता है, और कभी-कभी अत्यधिक कष्टदायक होता है। हालांकि हमारी रिबेस-मेन स्क्रिप्ट के लिए यह कोई समस्या नहीं है, और एकमात्र संकेत है कि ऐसा हो रहा है कि हमने स्क्रिप्ट स्थान को पूर्ण पथ के रूप में संदर्भित करने के लिए फ़ाइल पथ में ~ का उपयोग किया है।

आपके गिट उपनामों में स्क्रिप्टिंग का परिचय आपके उपनामों में अधिक से अधिक तर्क जोड़ने को भी आकर्षक बना सकता है। इससे उन्हें बनाए रखना और समझना कठिन हो सकता है, लेकिन याद रखना भी कठिन हो सकता है। यह एक अति जटिल उपनाम बनाए रखने के लायक नहीं है, क्योंकि वैसे भी आपके द्वारा इसका उपयोग करने की संभावना कम होगी। इसके अतिरिक्त, आपको ऐसी किसी भी चीज़ को शामिल न करने के प्रति सावधान रहना चाहिए जिसे आपके उपनामों में चलने में बहुत अधिक समय लग सकता है। यदि आप कोई ऐसी स्क्रिप्ट चला रहे हैं जिसे चलने में लंबा समय लगता है, तो आप इस पर विचार करना चाहेंगे कि क्या यह इसके लिए सही जगह है।

निष्कर्ष

मुझे आशा है कि इस लेख ने आपको अपने गिट उपनामों में स्क्रिप्टिंग की शक्ति दिखाई है। स्क्रिप्ट का उपयोग करके आप अधिक जटिल उपनाम बना सकते हैं जिन्हें बनाए रखना और समझना आसान है। यह आपके गिट वर्कफ़्लो को अधिक कुशल और आनंददायक बना सकता है। Git उपनामों के अधिक उदाहरणों के लिए, आप मेरे dotfiles प्रोजेक्ट को देख सकते हैं। इसमें बहुत सारा कॉन्फ़िगरेशन शामिल है जिसे मैं अपनी सभी मशीनों पर रखता हूं, जिसमें मेरे गिट उपनाम भी शामिल हैं।

विज्ञप्ति वक्तव्य यह लेख यहां पुन: प्रस्तुत किया गया है: https://dev.to/agentender/superpowered-git-aliases-using-scripting-4odf?1 यदि कोई उल्लंघन है, तो कृपया इसे हटाने के लिए [email protected] से संपर्क करें।
नवीनतम ट्यूटोरियल अधिक>

चीनी भाषा का अध्ययन करें

अस्वीकरण: उपलब्ध कराए गए सभी संसाधन आंशिक रूप से इंटरनेट से हैं। यदि आपके कॉपीराइट या अन्य अधिकारों और हितों का कोई उल्लंघन होता है, तो कृपया विस्तृत कारण बताएं और कॉपीराइट या अधिकारों और हितों का प्रमाण प्रदान करें और फिर इसे ईमेल पर भेजें: [email protected] हम इसे आपके लिए यथाशीघ्र संभालेंगे।

Copyright© 2022 湘ICP备2022001581号-3