/git-worktree-relative

Bash script to enable git-worktree to use relative path

Primary LanguageShell

git-worktree-relative

Background

My solution

  • Bash script to replace the content of {worktree}/.git file and {repo}/.git/worktrees/{wtname}/gitdir
  • Why bash: almost everyone who use git will use it in some kind of bash-shell-like environment (ex: bash shell in linux, git bash in windows)
  • Requirements (should be available on every bash shell):
  • Another bash script to change it back to absolute path (since git worktree remove may refuse on relative path)

Usage

  • Execute the script in your worktree (or supply the worktree directory path in -w options)
  • It will read path to repository from {worktree}/.git file
  • Options:
    • -v = verbose
    • -d = dry run (do not write any change, use with verbose to show what this script do)
    • -w worktree_target = directory of worktree to be made relative (will default to current directory if not supplied)
    • -r repository_target = directory of repository (including worktree directory inside .git, will be read from {worktree_target}/.git file if not supplied)
    • -h = show help
  • This solution works for broken link (ex: worktree directory moved OR parent git directory moved): just supply the repository path in -r repositor_target flag
  • This solution works for worktree inside parent repository
  • example:
    • repository in /home/myuser/repo/myproject ; worktree in /home/myuser/www/myproject ; worktree is connected with repository (link is not broken)
      cd /home/myuser/www/myproject
      git worktree-relative
      # OR
      git worktree-relative -w /home/myuser/www/myproject
    • repository in /home/myuser/repo/myproject ; worktree in /home/myuser/www/myproject ; worktree is NOT connected with repository (link broken)
      cd /home/myuser/www/myproject
      git worktree-relative -r /home/myuser/repo/myproject/.git/worktrees/myproject
      # OR
      git worktree-relative -w /home/myuser/www/myproject -r /home/myuser/repo/myproject/.git/worktrees/myproject
    • to detect if link is broken, run command 'git status' in worktree directory
  • Reversing relative worktree back to absolute: just change git worktree-relative command with git worktree-absolute (same command line argument)
    • command git worktree remove requires the path to be absolute: you can use this reverse script to revert it back to absolute path before removing

Installation

Automatic Installation

  • copy paste below command into your terminal:
git clone https://github.com/Kristian-Tan/git-worktree-relative.git
cd git-worktree-relative
sudo bash install.sh
  • or this one-line: git clone https://github.com/Kristian-Tan/git-worktree-relative.git ; cd git-worktree-relative ; sudo bash install.sh
  • or another one-line: /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Kristian-Tan/git-worktree-relative/HEAD/get)"

Manual Installation

  • installation for all users:
    • copy git-worktree-relative.sh and git-worktree-absolute.sh to /usr/bin or /bin (you can also remove the extension)
    • give other user permission to execute it
    • example:
      cp git-worktree-relative.sh /usr/bin/git-worktree-relative
      cp git-worktree-absolute.sh /usr/bin/git-worktree-absolute
      chown root:root /usr/bin/git-worktree-relative
      chown root:root /usr/bin/git-worktree-absolute
      chmod 0755 /usr/bin/git-worktree-relative
      chmod 0755 /usr/bin/git-worktree-absolute
  • installation for one user:
    • copy it to any directory that is added to your PATH variable

Uninstallation

  • just remove copied files (or just use uninstall.sh script: git clone https://github.com/Kristian-Tan/git-worktree-relative.git ; sudo bash git-worktree-relative/uninstall.sh)
  • or another one-line: /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Kristian-Tan/git-worktree-relative/HEAD/remove)"
Installation on macOS
  • installation on macOS might encounter problem such as tac: command not found or readlink: illegal option -- f
  • the cause is because macOS does not have tac and have their own implementation of readlink
  • easiest workaround is by installing gnu coreutils with homebrew:
      brew install coreutils
      ln -s /usr/local/bin/greadlink /usr/local/bin/readlink
  • after that, you can continue installation and usage as normal

Contributing

  • Feel free to create issue, pull request, etc if there's anything that can be improved

Credits