"일꾼이 일을 잘하려면 먼저 도구를 갈고 닦아야 한다." - 공자, 『논어』.
첫 장 > 프로그램 작성 > 스크립팅을 사용한 강력한 Git 별칭

스크립팅을 사용한 강력한 Git 별칭

2024-11-08에 게시됨
검색:907

Superpowered Git Aliases using Scripting

Git 별칭이란 무엇입니까?

Git 별칭은 셸의 일반 별칭과 유사하게 작동하지만 Git 명령에만 적용됩니다. 이를 통해 더 긴 명령에 대한 바로 가기를 만들거나 기본적으로 사용할 수 없는 새 명령을 만들 수 있습니다.

별칭은 다른 git 명령과 동일한 셸 환경에서 실행되며 대부분 일반적인 작업 흐름을 단순화하는 데 사용됩니다.

단순 별칭

간단한 별칭은 인수 집합을 사용하여 단일 Git 명령을 호출합니다. 예를 들어 별칭:
를 사용하여 git status를 실행하여 저장소의 상태를 표시하는 별칭을 만들 수 있습니다.

[alias]
  s = status

그런 다음 git s를 실행하여 저장소 상태를 표시할 수 있습니다. ~/.gitconfig에 별칭을 구성했기 때문에 시스템의 모든 저장소에서 사용할 수 있습니다.

더 복잡한 별칭

임의의 셸 명령을 실행하는 git 별칭을 만들 수도 있습니다. 이렇게 하려면 별칭이 !로 시작해야 합니다. 이는 git 하위 명령이 아닌 것처럼 별칭을 실행하도록 git에 지시합니다. 예를 들어, 두 개의 git 명령을 순서대로 실행하려면 쉘 명령을 실행하는 별칭을 만들 수 있습니다:

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

이 별칭은 git my-alias를 실행할 때 git fetch 및 git rebase Origin/main을 순서대로 실행합니다.

git 별칭의 한 가지 제한 사항은 여러 줄 값으로 설정할 수 없다는 것입니다. 이는 보다 복잡한 별칭의 경우 이를 축소해야 함을 의미합니다.

또한 INI 파일에서 ; 문자는 줄의 나머지 부분을 주석 처리하는 데 사용됩니다. 이는 다음을 사용할 수 없음을 의미합니다. 별칭 명령에.

이 두 가지 제한으로 인해 표준 git 별칭 구문을 사용하여 더 복잡한 별칭을 만드는 것이 어려울 수 있지만 여전히 가능합니다. 예를 들어 if를 사용하여 분기하는 별칭은 다음과 같습니다.

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

이러한 제한으로 인해 내부에 모든 형태의 제어 흐름이 있는 별칭을 만들고 유지 관리하는 것이 훨씬 더 복잡해졌습니다. 여기서 스크립팅이 필요합니다.

스크립트를 사용하여 별칭 설정

원하는 프로그래밍 언어를 사용하여 gitalias를 스크립팅할 수 있습니다. Bash 스크립팅에 익숙하고 이를 사용하고 싶다면 원하는 git 명령을 실행하는 bash 스크립트를 생성할 수 있습니다. 사실 저는 JavaScript를 사용하는 것이 훨씬 더 강하므로 이를 사용하겠습니다.

또 다른 주요 이점은 스크립팅 언어를 사용하면 별칭이 인수를 훨씬 받아들이고 작동할 수 있다는 것입니다. Git은 CLI에서 전달한 모든 인수를 명령 끝에 추가하여 별칭에 전달합니다. 따라서 스크립트는 문제 없이 읽을 수 있어야 합니다. 예를 들어 Node JS에서는 process.argv에서 스크립트에 직접 전달된 인수에 액세스할 수 있습니다.

이 설정을 위한 기본 단계는 선택한 언어에 따라 변경되지 않습니다. 다음을 수행해야 합니다.

  • 원하는 git 명령을 실행하는 스크립트 생성
  • 스크립트를 실행하는 별칭 작성

사례 연구: 메인/마스터 리베이스

최근 몇 년 동안 새 저장소의 기본 분기 이름이 마스터에서 메인으로 변경되었습니다. 이는 새 저장소를 복제할 때 기본 분기가 마스터가 아닌 기본 분기가 될 수 있음을 의미합니다. 생태계가 전환되고 있기 때문에 더 이상 매우 일관된 이름이 없습니다. 이는 전반적으로 좋은 일이지만 위의 리베이스 별칭이 모든 경우에 작동하지는 않는다는 것을 의미합니다.

별칭을 업데이트하여 브랜치가 메인인지 마스터인지 확인한 다음 올바른 브랜치를 리베이스해야 합니다. 이는 스크립트의 완벽한 사용 사례입니다.

#!/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'});

현재 스크립트를 실행하려면 node ~/gitaliases/git-rebase-main.js를 실행해야 합니다. 이는 이상적이지 않으며 습관적으로 할 수 있는 일도 아닙니다. 스크립트를 실행하는 git 별칭을 생성하면 이를 더 쉽게 만들 수 있습니다.

[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 파일로 추출할 수도 있지만 노드에 보관하면 개인적으로 유지 관리 부담이 줄어듭니다. 과거에는 이 별칭을 업데이트해야 할 때마다 이를 bash linter에 붙여넣고 변경하고 축소한 다음 다시 gitconfig에 붙여넣어야 했습니다. 이는 고통스러운 일이었으며 이로 인해 별칭 업데이트를 피하는 경우가 많았습니다. 이제 스크립트 파일에 있으므로 다른 스크립트처럼 업데이트할 수 있습니다.

몇 가지 주의 사항

별칭을 스크립트로 설정하면 Git 별칭에서 완전히 새로운 수준의 기능을 사용할 수 있습니다. 다만, 이 작업을 할 때 주의할 점이 있습니다.

이와 같은 별칭을 설정할 때 스크립트의 cwd가 스크립트를 실행하는 셸의 현재 작업 디렉터리가 된다는 점을 기억하는 것이 중요합니다. 스크립트의 모든 상대 파일 경로는 스크립트 위치가 아닌 셸의 cwd를 기준으로 처리됩니다. 이것은 때로는 매우 유용하지만 다른 경우에는 매우 고통스럽습니다. rebase-main 스크립트의 경우 이는 문제가 되지 않으며, 이런 일이 발생하고 있다는 유일한 표시는 스크립트 위치를 절대 경로로 참조하기 위해 파일 경로에서 ~를 사용했다는 것입니다.

git 별칭에 스크립팅을 도입하면 별칭에 더 많은 논리를 추가하고 싶은 유혹이 생길 수도 있습니다. 이로 인해 유지 관리 및 이해가 더 어려워질 수 있지만 기억하기도 더 어려워집니다. 어쨌든 사용할 가능성이 적기 때문에 매우 복잡한 별칭을 유지 관리할 가치가 없습니다. 또한 별칭을 실행하는 데 너무 오랜 시간이 걸릴 수 있는 항목을 도입하지 않도록 주의해야 합니다. 실행하는 데 오랜 시간이 걸리는 스크립트를 실행하는 경우 해당 스크립트가 적합한 위치인지 고려해 볼 수 있습니다.

결론

이 기사를 통해 Git 별칭의 스크립팅이 얼마나 강력한지 알 수 있었기를 바랍니다. 스크립트를 사용하면 유지 관리 및 이해가 더 쉬운 보다 복잡한 별칭을 만들 수 있습니다. 이를 통해 Git 작업 흐름을 더욱 효율적이고 즐겁게 만들 수 있습니다. git 별칭의 더 많은 예를 보려면 내 dotfiles 프로젝트를 참조하세요. 여기에는 Git 별칭을 포함하여 모든 컴퓨터에서 유지하는 많은 구성이 포함되어 있습니다.

릴리스 선언문 이 글은 https://dev.to/agentender/superpowered-git-aliases-using-scripting-4odf?1에서 복제됩니다. 침해 내용이 있는 경우, [email protected]으로 연락하여 삭제하시기 바랍니다.
최신 튜토리얼 더>

부인 성명: 제공된 모든 리소스는 부분적으로 인터넷에서 가져온 것입니다. 귀하의 저작권이나 기타 권리 및 이익이 침해된 경우 자세한 이유를 설명하고 저작권 또는 권리 및 이익에 대한 증거를 제공한 후 이메일([email protected])로 보내주십시오. 최대한 빨리 처리해 드리겠습니다.

Copyright© 2022 湘ICP备2022001581号-3