rel:: [[distributed version control|DVCS]] # git ## Reference - [git-sim](https://initialcommit.com/blog/git-sim) - visually simulate git operations - [inside .git](https://jvns.ca/blog/2024/01/26/inside-git/) - [git tips and tricks](https://blog.gitbutler.com/git-tips-and-tricks/) - [common git config options](https://readwise.io/reader/shared/01hpsftrsssp238jeaqr35ntnq) ([[Julia Evans]]) - [bfg](https://rtyley.github.io/bfg-repo-cleaner/) - repo cleaner ## Machete For stacked branch workflows. It's worth going through [a git machete tutorial](https://medium.com/virtuslab/make-your-way-through-the-git-rebase-jungle-with-git-machete-e2ed4dbacd02) and learning its model. git doesn't have a concept of branch hierarchy itself, so machete brings its own mapping (visible with the status and edit commands). ### My workflow #### `.gitconfig` Aliases ``` [alias] m = machete sync = "!sync() { git machete traverse -yW --push; }; sync" cpr = "!cpr() { git machete github create-pr --draft && git machete anno $(git machete anno) update=merge; }; cpr" ``` #### Common Actions ``` # register current branch with machete # it will try to infer the "parent" branch and it nearly always guesses right git m add # see status and tree relationships of your branches git m s # creates a PR from the current branch, marking it to merge instead of rebase whenever I sync git cpr # pulls latest trunk and recursively rebases dependent branches # if a branch has a PR associated with it (the update=merge annotation in the 'cpr' alias), the sync will merge instead of rebase git sync # edit the machete branch relationship tree # only need this on occasion, the format is just plain text with child branches indented under their parents git m e ``` ## Cookbook ### Recovering from a `git push -f` with [[GitHub]] > [!note] >If you've force-pushed to a branch only you are working on, the easiest is to use `git reflog` and `git reset` followed by another force push. This procedure is useful if you've force-pushed to a shared branch and your local branch was out-of-date. ```bash # First, populate the GITHUB_TOKEN env var with an access token from https://github.com/settings/tokens # find good sha from previous events, look for recent changes to <BROKEN_BRANCH> curl --header "Authorization: Bearer $GITHUB_TOKEN" \ https://api.github.com/repos/:owner/:repo/events # create a remote branch with good sha from event log curl --header "Authorization: Bearer $GITHUB_TOKEN" \ -X POST -d '{"ref":"refs/heads/<FIX_BRANCH>", "sha":"<SHA FROM_EVENT_LOG>"}' \ https://api.github.com/repos/:owner/:repo/git/refs # fix git fetch git checkout <BROKEN_BRANCH> git reset --hard origin/<FIX_BRANCH> git push -f origin <BROKEN_BRANCH> ```