# Git - Miscellaneous Assorted tips and commands. ## Switch to Previous Branch Like [[Bash and Zsh#Directory Stack (`cd -`, `pushd`, `popd`)|cd -]] for directories, git can jump back to previous branches. Git records every branch switch in the reflog. List recent switches with: ```bash git reflog | grep 'checkout:' ``` You can reference the Nth previous branch using the `@{-N}` syntax — it works anywhere git accepts a revision (`switch`, `checkout`, `merge`, `rebase`, `log`, etc.): | Command | Meaning | |---------|---------| | `git switch -` | Previous branch (shorthand for `@{-1}`) | | `git switch @{-2}` | 2 checkouts ago | | `git switch @{-N}` | N checkouts ago | | `git checkout -` | Same as `git switch -` | | `git checkout @{-N}` | Same as `git switch @{-N}` | `@{-N}` works anywhere git accepts a revision — `merge`, `rebase`, `log`, etc. Note: `git checkout -2` does **not** work — the full `@{-N}` form is required for N > 1. ## Cherry-Pick Commits onto a New Branch Quick workflow for taking existing commits and opening a PR from a clean branch: ```bash git checkout -b fix/thing master # new branch from master git cherry-pick <sha1> <sha2> # pick the commits git checkout - # back to where you were ``` If you have unstaged changes, stash first (`gsta`) or commit them before branching. ## Remove (remote) branch locally [source](https://stackoverflow.com/questions/28258679/how-to-remove-a-branch-locally) ```bash git branch -d -r origin/master ``` And to remove all: [source](https://stackoverflow.com/questions/41350191/delete-all-remote-tracking-branches-for-a-remote-git-repository/41576929#41576929) ```bash git branch -rd $( git branch -r | grep 'wr/' ) ``` ## Manage file permissions on Windows [source](https://stackoverflow.com/questions/6476513/git-file-permissions-on-windows#13593391) `git update-index --chmod=+x <file>` ## List all files in a commit [source](https://stackoverflow.com/questions/424071/how-do-i-list-all-the-files-in-a-commit) How can I print a plain list of all files that were part of a given commit? Although the following lists the files, it also includes unwanted diff information for each: ```bash git show a303aa90779efdd2f6b9d90693e2cbbbe4613c1d ``` > I'll just assume that [`gitk`](https://git-scm.com/docs/gitk) is not desired for this. In that case, try `git show --name-only <sha>`. > > — [SO answer](https://stackoverflow.com/questions/424071/how-do-i-list-all-the-files-in-a-commit) ## `HEAD~<n>` vs `HEAD^<n>` [source](https://stackoverflow.com/a/2222920/4700312) ### Rules of thumb - Use `~` most of the time — to go back a number of generations, usually what you want - Use `^` on merge commits — because they have two or more (immediate) parents Mnemonics: - Tilde `~` is almost linear in appearance and wants to go backward in a straight line - Caret `^` suggests an interesting segment of a tree or a fork in the road ## Who is "us" and who is "them"? [source](https://stackoverflow.com/questions/21025314/who-is-us-and-who-is-them-according-to-git) ## Permissions for 'private-key' are too open SSH refuses to use a private key if other users can read it. Keys must only be accessible to the user they're intended for and no other account, service, or group. **macOS/Linux:** ```bash chmod 600 ~/.ssh/id_rsa ``` **Windows GUI:** File Properties → Security → Advanced - Owner: Change → Select a principal → Enter key's user → OK - Permission Entries: Remove all except for the key's user - Set key's user to Full Control if not already set **Windows CMD:** ```cmd Set Key="%UserProfile%\.ssh\id_rsa" :: Remove Inheritance: Icacls %Key% /c /t /Inheritance:d :: Set Ownership to Owner: :: Key's within %UserProfile%: Icacls %Key% /c /t /Grant %UserName%:F :: Key's outside of %UserProfile%: TakeOwn /F %Key% Icacls %Key% /c /t /Grant:r %UserName%:F :: Remove All Users, except for Owner: Icacls %Key% /c /t /Remove:g "Authenticated Users" BUILTIN\Administrators BUILTIN Everyone System Users :: Verify: Icacls %Key% set "Key=" ``` **PowerShell:** ```powershell New-Variable -Name Key -Value "$env:UserProfile\.ssh\id_rsa" # Remove Inheritance: Icacls $Key /c /t /Inheritance:d # Set Ownership to Owner: # Key's within $env:UserProfile: Icacls $Key /c /t /Grant ${env:UserName}:F # Key's outside of $env:UserProfile: TakeOwn /F $Key Icacls $Key /c /t /Grant:r ${env:UserName}:F # Remove All Users, except for Owner: Icacls $Key /c /t /Remove:g Administrator "Authenticated Users" BUILTIN\Administrators BUILTIN Everyone System Users # Verify: Icacls $Key Remove-Variable -Name Key ``` ([source](https://superuser.com/a/1329702/744283))