├── contents ├── .gitkeep ├── check-existing-worktrees.md ├── useful-rare-git-commands-you-never-heard-of.md ├── patch-vs-diff-quick-reference.md ├── flags-and-their-uses.md ├── switch-between-worktrees.md ├── git-command-reference-full-list.md ├── git-init-bare.md ├── git-replace-old-commit-new-commit.md ├── show-commit-history-of-a-specific-file.md ├── apply-diff-file.md ├── remove-a-worktree.md ├── use-worktrees-for-temporary-fixes.md ├── create-a-new-worktree.md ├── past-commits-of-a-specific-file.md ├── apply-patch-with-commit-metadata.md ├── how-to-use-git-worktree-safely.md ├── sharing-changes-as-patch-files.md ├── show-detailed-commit-history-with-changes.md ├── git-essentials-hidden-gems.md ├── see-who-last-modified-each-line-blame.md ├── git-clone-mirror-repository.md ├── show-commit-history-with-author-and-date.md ├── create-patch-from-uncommitted-changes.md ├── cleanup-branches-fast.md ├── create-patch-from-last-commit-s.md ├── how-to-use-git-push-force-with-lease-safely.md ├── view-and-clean-up-local-git-branches-bash.md ├── view-and-clean-up-local-git-branches-powershell.md ├── delete-local-branches-whose-remote-is-gone-bash.md ├── git-maintenance-start.md ├── delete-local-branches-whose-remote-is-gone-powershell.md ├── git-clean-remove-untracked-files-and-directories.md ├── git-request-pull.md └── pull-changes-of-specific-files-from-a-commit.md ├── .vscode └── extensions.json ├── brand ├── advanced-git-mike-rambil.png └── advanced-git-mike-rambil.webp ├── CONTRIBUTING.md ├── .github ├── workflows │ ├── force-generate-readme.yml │ ├── generate-readme.yml │ └── issue-to-toc.yml └── ISSUE_TEMPLATE │ └── command-submission.yml ├── dev-docs └── FORMAT.md ├── README.md ├── scripts ├── issue-to-toc.js └── generate-readme.js └── toc-source.json /contents/.gitkeep: -------------------------------------------------------------------------------- 1 | Keep this file to ensure the contents directory is created. -------------------------------------------------------------------------------- /.vscode/extensions.json: -------------------------------------------------------------------------------- 1 | { 2 | "recommendations": ["yzhang.markdown-all-in-one"] 3 | } 4 | -------------------------------------------------------------------------------- /brand/advanced-git-mike-rambil.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mike-rambil/Advanced-Git/HEAD/brand/advanced-git-mike-rambil.png -------------------------------------------------------------------------------- /brand/advanced-git-mike-rambil.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mike-rambil/Advanced-Git/HEAD/brand/advanced-git-mike-rambil.webp -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | # Contributors & Credits 4 | 5 | ## 👨‍👩‍👧‍👦Contributors 6 | 7 | [@mike-rambil](https://github.com/mike-rambil) 8 | 9 | ## 📚 Credits & Authors 10 | [Sagil Bhatia](https://medium.com/@sahilsahilbhatia) 11 | 12 | ## 🔗 Blogs & Articles 13 | - [git-push-force-with-lease-vs-force](https://medium.com/@sahilsahilbhatia/git-push-force-with-lease-vs-force-ecae72601e80) 14 | 15 | 16 | -------------------------------------------------------------------------------- /.github/workflows/force-generate-readme.yml: -------------------------------------------------------------------------------- 1 | name: Force Generate All Docs 2 | 3 | on: 4 | workflow_dispatch: 5 | 6 | jobs: 7 | force-generate: 8 | runs-on: ubuntu-latest 9 | steps: 10 | - uses: actions/checkout@v3 11 | - name: Set up Node.js 12 | uses: actions/setup-node@v3 13 | with: 14 | node-version: '18' 15 | - name: Force generate all markdown files and README 16 | run: | 17 | node scripts/generate-readme.js 18 | - name: Commit and push changes 19 | run: | 20 | git config --global user.name 'github-actions[bot]' 21 | git config --global user.email 'github-actions[bot]@users.noreply.github.com' 22 | git add README.md contents/ 23 | git commit -m 'chore: force-generate all markdown files and README.md' || echo "No changes to commit" 24 | git push 25 | -------------------------------------------------------------------------------- /contents/check-existing-worktrees.md: -------------------------------------------------------------------------------- 1 | [⬅️ Back to How to Use git worktree Safely](https://github.com/mike-rambil/Advanced-Git/blob/main/contents/how-to-use-git-worktree-safely.md) 2 | 3 | # Check Existing Worktrees 4 | 5 | 6 | ![Category: Worktree](https://img.shields.io/badge/Category-Worktree-blue) 7 | 8 | #### Command 9 | ```sh 10 | git worktree list 11 | ``` 12 | 13 | #### Examples 14 | - **List all active worktrees.** 15 | 16 | ```sh 17 | git worktree list 18 | ``` 19 | - **List worktrees in a machine-readable format.** 20 | 21 | ```sh 22 | git worktree list --porcelain 23 | ``` 24 | 25 | 26 | #### Steps 27 | 1. List all active worktrees. 28 | 29 | 30 | [➡️ See the Next Step: Create a New Worktree](https://github.com/mike-rambil/Advanced-Git/blob/main/contents/create-a-new-worktree.md) 31 | 32 | --- 33 | 34 | _Author: mike-rambil • Updated: 2024-06-10 • Tags: worktree, list_ 35 | -------------------------------------------------------------------------------- /contents/useful-rare-git-commands-you-never-heard-of.md: -------------------------------------------------------------------------------- 1 | [⬅️ Back to Table of Contents](https://github.com/mike-rambil/Advanced-Git/blob/main/README.md#useful-rare-git-commands-you-never-heard-of) 2 | 3 | # Useful Rare Git Commands You Never Heard Of 4 | 5 | 6 | ![Category: Advanced](https://img.shields.io/badge/Category-Advanced-blue) 7 | > A collection of lesser-known but powerful Git commands. 8 | 9 | A collection of lesser-known but powerful Git commands. Use these to level up your Git workflow! 10 | 11 | ## Key Topics & Subcommands 12 | - [git replace ](./git-replace-old-commit-new-commit.md): Temporarily substitute one commit for another. 13 | 14 | 15 | [➡️ Continue to Next Topic: How to Use git push --force-with-lease Safely](https://github.com/mike-rambil/Advanced-Git/blob/main/contents/how-to-use-git-push-force-with-lease-safely.md) 16 | 17 | --- 18 | 19 | _Author: mike-rambil • Updated: 2024-06-10 • Tags: rare, advanced, tips_ 20 | -------------------------------------------------------------------------------- /.github/workflows/generate-readme.yml: -------------------------------------------------------------------------------- 1 | name: Generate README 2 | 3 | on: 4 | workflow_dispatch: 5 | push: 6 | paths: 7 | - 'toc-source.json' 8 | - '.github/workflows/generate-readme.yml' 9 | - 'scripts/generate-readme.js' 10 | 11 | jobs: 12 | build: 13 | runs-on: ubuntu-latest 14 | steps: 15 | - uses: actions/checkout@v3 16 | - name: Set up Node.js 17 | uses: actions/setup-node@v3 18 | with: 19 | node-version: '18' 20 | - name: Generate README.md 21 | run: | 22 | node scripts/generate-readme.js 23 | - name: Commit and push changes 24 | run: | 25 | git config --global user.name 'github-actions[bot]' 26 | git config --global user.email 'github-actions[bot]@users.noreply.github.com' 27 | git add README.md contents/ 28 | git commit -m 'chore: auto-generate README.md from toc-source.json' || echo "No changes to commit" 29 | git push 30 | -------------------------------------------------------------------------------- /contents/patch-vs-diff-quick-reference.md: -------------------------------------------------------------------------------- 1 | [⬅️ Back to Sharing Changes as Patch Files](https://github.com/mike-rambil/Advanced-Git/blob/main/contents/sharing-changes-as-patch-files.md) 2 | 3 | [⬆️ Previous Step: Apply Diff File](https://github.com/mike-rambil/Advanced-Git/blob/main/contents/apply-diff-file.md) 4 | 5 | # Patch vs Diff: Quick Reference 6 | 7 | 8 | ![Category: Patch & Diff](https://img.shields.io/badge/Category-Patch%20%26%20Diff-blue) 9 | | Command | Use Case | Preserves Commit Info? | Can Apply With | 10 | |---|---|---|---| 11 | | git diff > file.diff | Share uncommitted changes | ❌ | git apply | 12 | | git format-patch > file.patch | Share committed changes | ✅ | git am | 13 | 14 | 15 | [➡️ Continue to Next Topic: Pull Changes of Specific Files from a Commit](https://github.com/mike-rambil/Advanced-Git/blob/main/contents/pull-changes-of-specific-files-from-a-commit.md) 16 | 17 | --- 18 | 19 | _Author: mike-rambil • Updated: 2024-06-10 • Tags: patch, diff, reference_ 20 | -------------------------------------------------------------------------------- /contents/flags-and-their-uses.md: -------------------------------------------------------------------------------- 1 | [⬅️ Back to How to Use git worktree Safely](https://github.com/mike-rambil/Advanced-Git/blob/main/contents/how-to-use-git-worktree-safely.md) 2 | 3 | [⬆️ Previous Step: Use Worktrees for Temporary Fixes](https://github.com/mike-rambil/Advanced-Git/blob/main/contents/use-worktrees-for-temporary-fixes.md) 4 | 5 | # Flags and Their Uses 6 | 7 | 8 | #### Flags 9 | - `add`: Creates a new worktree for an existing branch. 10 | - `-b`: Creates a new worktree with a new branch. 11 | - `list`: Lists all active worktrees. 12 | - `remove`: Detaches a worktree from the repo without deleting files. 13 | - `prune`: Cleans up stale worktree references after manual deletion. 14 | - `move`: Moves a worktree to a different location. 15 | 16 | 17 | [➡️ Continue to Next Topic: Sharing Changes as Patch Files](https://github.com/mike-rambil/Advanced-Git/blob/main/contents/sharing-changes-as-patch-files.md) 18 | 19 | --- 20 | 21 | _Author: mike-rambil • Updated: 2024-06-10 • Tags: worktree, flags_ 22 | -------------------------------------------------------------------------------- /contents/switch-between-worktrees.md: -------------------------------------------------------------------------------- 1 | [⬅️ Back to How to Use git worktree Safely](https://github.com/mike-rambil/Advanced-Git/blob/main/contents/how-to-use-git-worktree-safely.md) 2 | 3 | [⬆️ Previous Step: Remove a Worktree](https://github.com/mike-rambil/Advanced-Git/blob/main/contents/remove-a-worktree.md) 4 | 5 | # Switch Between Worktrees 6 | 7 | 8 | ![Category: Worktree](https://img.shields.io/badge/Category-Worktree-blue) 9 | 10 | #### Command 11 | `cd ` 12 | 13 | #### Examples 14 | - **Switch to the worktree directory.** 15 | 16 | ```sh 17 | cd ../feature-branch 18 | ``` 19 | - **Switch to a hotfix worktree.** 20 | 21 | ```sh 22 | cd ../hotfix 23 | ``` 24 | 25 | 26 | #### Steps 27 | 1. Simply cd into the worktree directory to switch. 28 | 29 | 30 | [➡️ See the Next Step: Use Worktrees for Temporary Fixes](https://github.com/mike-rambil/Advanced-Git/blob/main/contents/use-worktrees-for-temporary-fixes.md) 31 | 32 | --- 33 | 34 | _Author: mike-rambil • Updated: 2024-06-10 • Tags: worktree, switch_ 35 | -------------------------------------------------------------------------------- /contents/git-command-reference-full-list.md: -------------------------------------------------------------------------------- 1 | [⬅️ Back to Table of Contents](https://github.com/mike-rambil/Advanced-Git/blob/main/README.md#git-command-reference-full-list) 2 | 3 | # Git Command Reference (Full List) 4 | 5 | 6 | ![Category: Reference](https://img.shields.io/badge/Category-Reference-blue) 7 | > A comprehensive list of Git commands used in this project. 8 | 9 | A comprehensive list of Git commands used in this project, formatted according to our standard. 10 | 11 | ## Key Topics & Subcommands 12 | - [git init --bare](./git-init-bare.md): Initialize a bare repository, typically used for remote repositories. 13 | - [git clone --mirror ](./git-clone-mirror-repository.md): Clone a repository in mirror mode, including all refs and branches. 14 | 15 | 16 | [➡️ Continue to Next Topic: Useful Rare Git Commands You Never Heard Of](https://github.com/mike-rambil/Advanced-Git/blob/main/contents/useful-rare-git-commands-you-never-heard-of.md) 17 | 18 | --- 19 | 20 | _Author: mike-rambil • Updated: 2024-06-10 • Tags: reference, all-commands_ 21 | -------------------------------------------------------------------------------- /contents/git-init-bare.md: -------------------------------------------------------------------------------- 1 | [⬅️ Back to Git Command Reference (Full List)](https://github.com/mike-rambil/Advanced-Git/blob/main/contents/git-command-reference-full-list.md) 2 | 3 | # git init --bare 4 | 5 | 6 | ![Category: Repository Management](https://img.shields.io/badge/Category-Repository%20Management-blue) 7 | > Initialize a bare repository, typically used for remote repositories. 8 | 9 | 10 | #### Command 11 | ```sh 12 | git init --bare my-repo.git 13 | ``` 14 | 15 | #### Examples 16 | - **Create a bare repository for collaboration.** 17 | 18 | ```sh 19 | git init --bare my-repo.git 20 | ``` 21 | - **Initialize a bare repo in a custom directory for server hosting.** 22 | 23 | ```sh 24 | git init --bare /srv/git/project.git 25 | ``` 26 | 27 | 28 | #### Steps 29 | 1. Run `git init --bare my-repo.git` to create a bare repository. 30 | 31 | 32 | [➡️ See the Next Step: git clone --mirror ](https://github.com/mike-rambil/Advanced-Git/blob/main/contents/git-clone-mirror-repository.md) 33 | 34 | --- 35 | 36 | _Author: mike-rambil • Updated: 2024-06-10 • Tags: init, bare, repository_ 37 | -------------------------------------------------------------------------------- /contents/git-replace-old-commit-new-commit.md: -------------------------------------------------------------------------------- 1 | [⬅️ Back to Useful Rare Git Commands You Never Heard Of](https://github.com/mike-rambil/Advanced-Git/blob/main/contents/useful-rare-git-commands-you-never-heard-of.md) 2 | 3 | # git replace 4 | 5 | 6 | ![Category: History](https://img.shields.io/badge/Category-History-blue) 7 | > Temporarily substitute one commit for another. 8 | 9 | 10 | #### Command 11 | ```sh 12 | git replace abc123 def456 13 | ``` 14 | 15 | #### Examples 16 | - **Temporarily replace commit abc123 with def456.** 17 | 18 | ```sh 19 | git replace abc123 def456 20 | ``` 21 | - **Graft a new parent onto a commit for testing history changes.** 22 | 23 | ```sh 24 | git replace --graft HEAD~2 HEAD 25 | ``` 26 | 27 | 28 | #### Steps 29 | 1. Run `git replace ` to test or patch history. 30 | 31 | 32 | [➡️ Continue to Next Topic: How to Use git push --force-with-lease Safely](https://github.com/mike-rambil/Advanced-Git/blob/main/contents/how-to-use-git-push-force-with-lease-safely.md) 33 | 34 | --- 35 | 36 | _Author: mike-rambil • Updated: 2024-06-10 • Tags: replace, history_ 37 | -------------------------------------------------------------------------------- /contents/show-commit-history-of-a-specific-file.md: -------------------------------------------------------------------------------- 1 | [⬅️ Back to Past commits of a specific file](https://github.com/mike-rambil/Advanced-Git/blob/main/contents/past-commits-of-a-specific-file.md) 2 | 3 | # Show Commit History of a Specific File 4 | 5 | 6 | ![Category: History](https://img.shields.io/badge/Category-History-blue) 7 | 8 | #### Command 9 | ```sh 10 | git log --oneline -- filename.txt 11 | ``` 12 | 13 | #### Examples 14 | - **List all commits that modified `filename.txt`.** 15 | 16 | ```sh 17 | git log --oneline -- filename.txt 18 | ``` 19 | - **Show commit history for a different file.** 20 | 21 | ```sh 22 | git log --oneline -- path/to/anotherfile.js 23 | ``` 24 | 25 | 26 | #### Steps 27 | 1. Lists all commits that modified `filename.txt`. 28 | 29 | 30 | #### Related Commands 31 | - git log -p -- filename.txt 32 | - git blame filename.txt 33 | 34 | 35 | [➡️ See the Next Step: Show Detailed Commit History (With Changes)](https://github.com/mike-rambil/Advanced-Git/blob/main/contents/show-detailed-commit-history-with-changes.md) 36 | 37 | --- 38 | 39 | _Author: mike-rambil • Updated: 2024-06-10 • Tags: log, file, history_ 40 | -------------------------------------------------------------------------------- /contents/apply-diff-file.md: -------------------------------------------------------------------------------- 1 | [⬅️ Back to Sharing Changes as Patch Files](https://github.com/mike-rambil/Advanced-Git/blob/main/contents/sharing-changes-as-patch-files.md) 2 | 3 | [⬆️ Previous Step: Create Patch from Uncommitted Changes](https://github.com/mike-rambil/Advanced-Git/blob/main/contents/create-patch-from-uncommitted-changes.md) 4 | 5 | # Apply Diff File 6 | 7 | 8 | ![Category: Patch & Diff](https://img.shields.io/badge/Category-Patch%20%26%20Diff-blue) 9 | 10 | #### Command 11 | ```sh 12 | git apply changes.diff 13 | ``` 14 | 15 | #### Examples 16 | - **Apply a diff file of uncommitted changes.** 17 | 18 | ```sh 19 | git apply changes.diff 20 | ``` 21 | - **Show what would change if the diff were applied.** 22 | 23 | ```sh 24 | git apply --stat changes.diff 25 | ``` 26 | 27 | 28 | #### Steps 29 | 1. Run '`git apply changes.diff' to apply the changes from a diff file`. 30 | 31 | 32 | [➡️ See the Next Step: Patch vs Diff: Quick Reference](https://github.com/mike-rambil/Advanced-Git/blob/main/contents/patch-vs-diff-quick-reference.md) 33 | 34 | --- 35 | 36 | _Author: mike-rambil • Updated: 2024-06-10 • Tags: diff, apply, uncommitted_ 37 | -------------------------------------------------------------------------------- /contents/remove-a-worktree.md: -------------------------------------------------------------------------------- 1 | [⬅️ Back to How to Use git worktree Safely](https://github.com/mike-rambil/Advanced-Git/blob/main/contents/how-to-use-git-worktree-safely.md) 2 | 3 | [⬆️ Previous Step: Create a New Worktree](https://github.com/mike-rambil/Advanced-Git/blob/main/contents/create-a-new-worktree.md) 4 | 5 | # Remove a Worktree 6 | 7 | 8 | ![Category: Worktree](https://img.shields.io/badge/Category-Worktree-blue) 9 | 10 | #### Command 11 | ```sh 12 | git worktree remove 13 | ``` 14 | 15 | #### Examples 16 | - **Detach a worktree without deleting the files.** 17 | 18 | ```sh 19 | git worktree remove ../feature-branch 20 | ``` 21 | - **Remove a hotfix worktree.** 22 | 23 | ```sh 24 | git worktree remove ../hotfix 25 | ``` 26 | 27 | 28 | #### Steps 29 | 1. Detach a worktree without deleting the files. 30 | 31 | 32 | #### Warnings 33 | - ⚠️ Make sure you have committed all changes before removing a worktree. 34 | 35 | 36 | [➡️ See the Next Step: Switch Between Worktrees](https://github.com/mike-rambil/Advanced-Git/blob/main/contents/switch-between-worktrees.md) 37 | 38 | --- 39 | 40 | _Author: mike-rambil • Updated: 2024-06-10 • Tags: worktree, remove_ 41 | -------------------------------------------------------------------------------- /contents/use-worktrees-for-temporary-fixes.md: -------------------------------------------------------------------------------- 1 | [⬅️ Back to How to Use git worktree Safely](https://github.com/mike-rambil/Advanced-Git/blob/main/contents/how-to-use-git-worktree-safely.md) 2 | 3 | [⬆️ Previous Step: Switch Between Worktrees](https://github.com/mike-rambil/Advanced-Git/blob/main/contents/switch-between-worktrees.md) 4 | 5 | # Use Worktrees for Temporary Fixes 6 | 7 | 8 | ![Category: Worktree](https://img.shields.io/badge/Category-Worktree-blue) 9 | 10 | #### Command 11 | ```sh 12 | git worktree add ../hotfix hotfix-branch 13 | ``` 14 | 15 | #### Examples 16 | - **Quickly apply a fix on another branch without leaving your main branch.** 17 | 18 | ```sh 19 | git worktree add ../hotfix hotfix-branch 20 | ``` 21 | - **Create a worktree for a bugfix branch.** 22 | 23 | ```sh 24 | git worktree add ../bugfix bugfix-branch 25 | ``` 26 | 27 | 28 | #### Steps 29 | 1. Quickly apply a fix on another branch without leaving your main branch. 30 | 31 | 32 | [➡️ See the Next Step: Flags and Their Uses](https://github.com/mike-rambil/Advanced-Git/blob/main/contents/flags-and-their-uses.md) 33 | 34 | --- 35 | 36 | _Author: mike-rambil • Updated: 2024-06-10 • Tags: worktree, hotfix_ 37 | -------------------------------------------------------------------------------- /contents/create-a-new-worktree.md: -------------------------------------------------------------------------------- 1 | [⬅️ Back to How to Use git worktree Safely](https://github.com/mike-rambil/Advanced-Git/blob/main/contents/how-to-use-git-worktree-safely.md) 2 | 3 | [⬆️ Previous Step: Check Existing Worktrees](https://github.com/mike-rambil/Advanced-Git/blob/main/contents/check-existing-worktrees.md) 4 | 5 | # Create a New Worktree 6 | 7 | 8 | ![Category: Worktree](https://img.shields.io/badge/Category-Worktree-blue) 9 | 10 | #### Command 11 | ```sh 12 | git worktree add 13 | ``` 14 | 15 | #### Examples 16 | - **Create a new worktree for the feature branch.** 17 | 18 | ```sh 19 | git worktree add ../feature-branch feature 20 | ``` 21 | - **Create a worktree for a hotfix branch.** 22 | 23 | ```sh 24 | git worktree add ../hotfix hotfix-branch 25 | ``` 26 | 27 | 28 | #### Steps 29 | 1. Create a worktree linked to a specific branch. 30 | 31 | 32 | #### Prerequisites 33 | - The target path must not already be a git repository. 34 | 35 | 36 | [➡️ See the Next Step: Remove a Worktree](https://github.com/mike-rambil/Advanced-Git/blob/main/contents/remove-a-worktree.md) 37 | 38 | --- 39 | 40 | _Author: mike-rambil • Updated: 2024-06-10 • Tags: worktree, add_ 41 | -------------------------------------------------------------------------------- /contents/past-commits-of-a-specific-file.md: -------------------------------------------------------------------------------- 1 | [⬅️ Back to Table of Contents](https://github.com/mike-rambil/Advanced-Git/blob/main/README.md#past-commits-of-a-specific-file) 2 | 3 | # Past commits of a specific file 4 | 5 | 6 | ![Category: History and Inspection](https://img.shields.io/badge/Category-History%20and%20Inspection-blue) 7 | > See all commits and changes for a specific file. 8 | 9 | You can see all commits related to a specific file using Git commands. Here are a few ways to do it: 10 | 11 | ## Key Topics & Subcommands 12 | - [Show Commit History of a Specific File](./show-commit-history-of-a-specific-file.md) 13 | - [Show Detailed Commit History (With Changes)](./show-detailed-commit-history-with-changes.md) 14 | - [Show Commit History With Author and Date](./show-commit-history-with-author-and-date.md) 15 | - [See Who Last Modified Each Line (Blame)](./see-who-last-modified-each-line-blame.md) 16 | 17 | 18 | [➡️ Continue to Next Topic: Git Clean: Remove Untracked Files and Directories](https://github.com/mike-rambil/Advanced-Git/blob/main/contents/git-clean-remove-untracked-files-and-directories.md) 19 | 20 | --- 21 | 22 | _Author: mike-rambil • Updated: 2024-06-10 • Tags: history, inspection, file_ 23 | -------------------------------------------------------------------------------- /contents/apply-patch-with-commit-metadata.md: -------------------------------------------------------------------------------- 1 | [⬅️ Back to Sharing Changes as Patch Files](https://github.com/mike-rambil/Advanced-Git/blob/main/contents/sharing-changes-as-patch-files.md) 2 | 3 | [⬆️ Previous Step: Create Patch from Last Commit(s)](https://github.com/mike-rambil/Advanced-Git/blob/main/contents/create-patch-from-last-commit-s.md) 4 | 5 | # Apply Patch with Commit Metadata 6 | 7 | 8 | ![Category: Patch & Diff](https://img.shields.io/badge/Category-Patch%20%26%20Diff-blue) 9 | 10 | #### Command 11 | ```sh 12 | git am my-changes.patch 13 | ``` 14 | 15 | #### Examples 16 | - **Apply a patch file and preserve commit info.** 17 | 18 | ```sh 19 | git am my-changes.patch 20 | ``` 21 | - **Apply a patch and add a Signed-off-by line.** 22 | 23 | ```sh 24 | git am --signoff my-changes.patch 25 | ``` 26 | 27 | 28 | #### Steps 29 | 1. Run '`git am my-changes.patch' to apply the patch and preserve commit messages, authorship, and timestamps`. 30 | 31 | 32 | [➡️ See the Next Step: Create Patch from Uncommitted Changes](https://github.com/mike-rambil/Advanced-Git/blob/main/contents/create-patch-from-uncommitted-changes.md) 33 | 34 | --- 35 | 36 | _Author: mike-rambil • Updated: 2024-06-10 • Tags: patch, am, apply_ 37 | -------------------------------------------------------------------------------- /contents/how-to-use-git-worktree-safely.md: -------------------------------------------------------------------------------- 1 | [⬅️ Back to Table of Contents](https://github.com/mike-rambil/Advanced-Git/blob/main/README.md#how-to-use-git-worktree-safely) 2 | 3 | # How to Use git worktree Safely 4 | 5 | 6 | ![Category: Worktree](https://img.shields.io/badge/Category-Worktree-blue) 7 | > Work on multiple branches simultaneously without switching. 8 | 9 | `git worktree` allows you to manage multiple working directories linked to a single Git repository. It helps developers work on multiple branches simultaneously without switching branches in the same directory. 10 | 11 | ## Key Topics & Subcommands 12 | - [Check Existing Worktrees](./check-existing-worktrees.md) 13 | - [Create a New Worktree](./create-a-new-worktree.md) 14 | - [Remove a Worktree](./remove-a-worktree.md) 15 | - [Switch Between Worktrees](./switch-between-worktrees.md) 16 | - [Use Worktrees for Temporary Fixes](./use-worktrees-for-temporary-fixes.md) 17 | - [Flags and Their Uses](./flags-and-their-uses.md) 18 | 19 | 20 | [➡️ Continue to Next Topic: Sharing Changes as Patch Files](https://github.com/mike-rambil/Advanced-Git/blob/main/contents/sharing-changes-as-patch-files.md) 21 | 22 | --- 23 | 24 | _Author: mike-rambil • Updated: 2024-06-10 • Tags: worktree, branches, advanced_ 25 | -------------------------------------------------------------------------------- /contents/sharing-changes-as-patch-files.md: -------------------------------------------------------------------------------- 1 | [⬅️ Back to Table of Contents](https://github.com/mike-rambil/Advanced-Git/blob/main/README.md#sharing-changes-as-patch-files) 2 | 3 | # Sharing Changes as Patch Files 4 | 5 | 6 | ![Category: Patch & Diff](https://img.shields.io/badge/Category-Patch%20%26%20Diff-blue) 7 | > Generate and share patch files for committed or uncommitted changes. 8 | 9 | How to create patch files from your changes for sharing via email, SCP, Slack, or other means. Covers both committed (with full commit metadata) and uncommitted changes. 10 | 11 | ## Key Topics & Subcommands 12 | - [Create Patch from Last Commit(s)](./create-patch-from-last-commit-s.md) 13 | - [Apply Patch with Commit Metadata](./apply-patch-with-commit-metadata.md) 14 | - [Create Patch from Uncommitted Changes](./create-patch-from-uncommitted-changes.md) 15 | - [Apply Diff File](./apply-diff-file.md) 16 | - [Patch vs Diff: Quick Reference](./patch-vs-diff-quick-reference.md) 17 | 18 | 19 | [➡️ Continue to Next Topic: Pull Changes of Specific Files from a Commit](https://github.com/mike-rambil/Advanced-Git/blob/main/contents/pull-changes-of-specific-files-from-a-commit.md) 20 | 21 | --- 22 | 23 | _Author: mike-rambil • Updated: 2024-06-10 • Tags: patch, diff, sharing, email, collaboration_ 24 | -------------------------------------------------------------------------------- /contents/show-detailed-commit-history-with-changes.md: -------------------------------------------------------------------------------- 1 | [⬅️ Back to Past commits of a specific file](https://github.com/mike-rambil/Advanced-Git/blob/main/contents/past-commits-of-a-specific-file.md) 2 | 3 | [⬆️ Previous Step: Show Commit History of a Specific File](https://github.com/mike-rambil/Advanced-Git/blob/main/contents/show-commit-history-of-a-specific-file.md) 4 | 5 | # Show Detailed Commit History (With Changes) 6 | 7 | 8 | ![Category: History](https://img.shields.io/badge/Category-History-blue) 9 | 10 | #### Command 11 | ```sh 12 | git log -p -- filename.txt 13 | ``` 14 | 15 | #### Examples 16 | - **Show each commit and the actual changes made to `filename.txt`.** 17 | 18 | ```sh 19 | git log -p -- filename.txt 20 | ``` 21 | - **Show the last two commits and their changes for a file.** 22 | 23 | ```sh 24 | git log -p -2 -- filename.txt 25 | ``` 26 | 27 | 28 | #### Steps 29 | 1. Shows each commit and the actual changes made to `filename.txt`. 30 | 31 | 32 | #### Related Commands 33 | - git log --oneline -- filename.txt 34 | 35 | 36 | [➡️ See the Next Step: Show Commit History With Author and Date](https://github.com/mike-rambil/Advanced-Git/blob/main/contents/show-commit-history-with-author-and-date.md) 37 | 38 | --- 39 | 40 | _Author: mike-rambil • Updated: 2024-06-10 • Tags: log, diff, file_ 41 | -------------------------------------------------------------------------------- /contents/git-essentials-hidden-gems.md: -------------------------------------------------------------------------------- 1 | [⬅️ Back to Table of Contents](https://github.com/mike-rambil/Advanced-Git/blob/main/README.md#git-essentials-hidden-gems) 2 | 3 | # Git Essentials & Hidden Gems 4 | 5 | 6 | ![Category: Miscellaneous](https://img.shields.io/badge/Category-Miscellaneous-blue) 7 | > Start here to discover commands that can improve your workflow and understanding of Git. 8 | 9 | A collection of practical, lesser-known, and foundational Git commands that are useful for all users. Start here to discover commands that can improve your workflow and understanding of Git. 10 | 11 | 12 | #### ProTips 13 | > [!TIP] 14 | > Try these commands in a test repo before using them on important projects. 15 | 16 | > [!TIP] 17 | > Bookmark this section for quick reference to hidden gems. 18 | 19 | 20 | ## Key Topics & Subcommands 21 | - [git maintenance start](./git-maintenance-start.md): Runs a cronJob in background for the specified repo for periodic maintenance. 22 | - [git request-pull](./git-request-pull.md): Generate a request to pull changes into a repository. 23 | 24 | 25 | [➡️ Continue to Next Topic: Cleanup Branches Fast ⚡](https://github.com/mike-rambil/Advanced-Git/blob/main/contents/cleanup-branches-fast.md) 26 | 27 | --- 28 | 29 | _Author: mike-rambil • Updated: 2024-06-10 • Tags: misc, cleanup, advanced_ 30 | -------------------------------------------------------------------------------- /contents/see-who-last-modified-each-line-blame.md: -------------------------------------------------------------------------------- 1 | [⬅️ Back to Past commits of a specific file](https://github.com/mike-rambil/Advanced-Git/blob/main/contents/past-commits-of-a-specific-file.md) 2 | 3 | [⬆️ Previous Step: Show Commit History With Author and Date](https://github.com/mike-rambil/Advanced-Git/blob/main/contents/show-commit-history-with-author-and-date.md) 4 | 5 | # See Who Last Modified Each Line (Blame) 6 | 7 | 8 | ![Category: History](https://img.shields.io/badge/Category-History-blue) 9 | 10 | #### Command 11 | ```sh 12 | git blame filename.txt 13 | ``` 14 | 15 | #### Examples 16 | - **Show the last commit that changed each line of the file.** 17 | 18 | ```sh 19 | git blame filename.txt 20 | ``` 21 | - **Blame only lines 10 to 20 of a file.** 22 | 23 | ```sh 24 | git blame -L 10,20 filename.txt 25 | ``` 26 | 27 | 28 | #### Steps 29 | 1. Shows the last commit that changed each line of the file. 30 | 31 | 32 | #### Warnings 33 | - ⚠️ Blame can be misleading if the file has been heavily refactored. 34 | 35 | 36 | [➡️ Continue to Next Topic: Git Clean: Remove Untracked Files and Directories](https://github.com/mike-rambil/Advanced-Git/blob/main/contents/git-clean-remove-untracked-files-and-directories.md) 37 | 38 | --- 39 | 40 | _Author: mike-rambil • Updated: 2024-06-10 • Tags: blame, file, history_ 41 | -------------------------------------------------------------------------------- /contents/git-clone-mirror-repository.md: -------------------------------------------------------------------------------- 1 | [⬅️ Back to Git Command Reference (Full List)](https://github.com/mike-rambil/Advanced-Git/blob/main/contents/git-command-reference-full-list.md) 2 | 3 | [⬆️ Previous Step: git init --bare](https://github.com/mike-rambil/Advanced-Git/blob/main/contents/git-init-bare.md) 4 | 5 | # git clone --mirror 6 | 7 | 8 | ![Category: Repository Management](https://img.shields.io/badge/Category-Repository%20Management-blue) 9 | > Clone a repository in mirror mode, including all refs and branches. 10 | 11 | 12 | #### Command 13 | ```sh 14 | git clone --mirror https://github.com/example/repo.git 15 | ``` 16 | 17 | #### Examples 18 | - **Create a full backup or migration of a repository.** 19 | 20 | ```sh 21 | git clone --mirror https://github.com/example/repo.git 22 | ``` 23 | - **Mirror-clone a private repo using SSH.** 24 | 25 | ```sh 26 | git clone --mirror git@github.com:org/repo.git 27 | ``` 28 | 29 | 30 | #### Steps 31 | 1. Run `git clone --mirror ` to create a full backup or migration. 32 | 33 | 34 | [➡️ Continue to Next Topic: Useful Rare Git Commands You Never Heard Of](https://github.com/mike-rambil/Advanced-Git/blob/main/contents/useful-rare-git-commands-you-never-heard-of.md) 35 | 36 | --- 37 | 38 | _Author: mike-rambil • Updated: 2024-06-10 • Tags: clone, mirror, backup_ 39 | -------------------------------------------------------------------------------- /contents/show-commit-history-with-author-and-date.md: -------------------------------------------------------------------------------- 1 | [⬅️ Back to Past commits of a specific file](https://github.com/mike-rambil/Advanced-Git/blob/main/contents/past-commits-of-a-specific-file.md) 2 | 3 | [⬆️ Previous Step: Show Detailed Commit History (With Changes)](https://github.com/mike-rambil/Advanced-Git/blob/main/contents/show-detailed-commit-history-with-changes.md) 4 | 5 | # Show Commit History With Author and Date 6 | 7 | 8 | ![Category: History](https://img.shields.io/badge/Category-History-blue) 9 | 10 | #### Command 11 | ```sh 12 | git log --pretty=format:"%h - %an, %ar : %s" -- filename.txt 13 | ``` 14 | 15 | #### Examples 16 | - **Display commit hash, author, relative date, and commit message.** 17 | 18 | ```sh 19 | git log --pretty=format:"%h - %an, %ar : %s" -- filename.txt 20 | ``` 21 | - **Show commit hash, short date, author, and message.** 22 | 23 | ```sh 24 | git log --pretty=format:'%h | %ad | %an | %s' --date=short -- filename.txt 25 | ``` 26 | 27 | 28 | #### Steps 29 | 1. Displays commit hash, author, relative date, and commit message. 30 | 31 | 32 | [➡️ See the Next Step: See Who Last Modified Each Line (Blame)](https://github.com/mike-rambil/Advanced-Git/blob/main/contents/see-who-last-modified-each-line-blame.md) 33 | 34 | --- 35 | 36 | _Author: mike-rambil • Updated: 2024-06-10 • Tags: log, author, date_ 37 | -------------------------------------------------------------------------------- /contents/create-patch-from-uncommitted-changes.md: -------------------------------------------------------------------------------- 1 | [⬅️ Back to Sharing Changes as Patch Files](https://github.com/mike-rambil/Advanced-Git/blob/main/contents/sharing-changes-as-patch-files.md) 2 | 3 | [⬆️ Previous Step: Apply Patch with Commit Metadata](https://github.com/mike-rambil/Advanced-Git/blob/main/contents/apply-patch-with-commit-metadata.md) 4 | 5 | # Create Patch from Uncommitted Changes 6 | 7 | 8 | ![Category: Patch & Diff](https://img.shields.io/badge/Category-Patch%20%26%20Diff-blue) 9 | 10 | #### Command 11 | ```sh 12 | git diff > changes.diff 13 | ``` 14 | 15 | #### Examples 16 | - **Create a diff file of uncommitted changes.** 17 | 18 | ```sh 19 | git diff > changes.diff 20 | ``` 21 | - **Create a diff file for the last commit.** 22 | 23 | ```sh 24 | git diff HEAD~1 > last-commit.diff 25 | ``` 26 | 27 | 28 | #### Steps 29 | 1. Run '`git diff > changes.diff' to save uncommitted changes to a file`. 30 | 31 | 32 | #### Warnings 33 | - ⚠️ This does NOT preserve commit metadata or history—just raw changes. 34 | 35 | 36 | #### Links 37 | - [Official Docs](https://git-scm.com/docs/git-diff) 38 | 39 | 40 | [➡️ See the Next Step: Apply Diff File](https://github.com/mike-rambil/Advanced-Git/blob/main/contents/apply-diff-file.md) 41 | 42 | --- 43 | 44 | _Author: mike-rambil • Updated: 2024-06-10 • Tags: diff, uncommitted, snapshot_ 45 | -------------------------------------------------------------------------------- /.github/workflows/issue-to-toc.yml: -------------------------------------------------------------------------------- 1 | name: "Convert Issue Submissions to TOC PR" 2 | 3 | on: 4 | issues: 5 | types: 6 | - opened 7 | 8 | permissions: 9 | contents: write 10 | pull-requests: write 11 | issues: read 12 | 13 | jobs: 14 | build: 15 | if: ${{ contains(join(github.event.issue.labels.*.name, ','), 'new command') }} 16 | runs-on: ubuntu-latest 17 | steps: 18 | - name: Checkout repository 19 | uses: actions/checkout@v4 20 | 21 | - name: Generate toc entry from issue 22 | run: node scripts/issue-to-toc.js 23 | env: 24 | ISSUE_BODY: ${{ github.event.issue.body }} 25 | ISSUE_NUMBER: ${{ github.event.issue.number }} 26 | 27 | - name: Create pull request 28 | uses: peter-evans/create-pull-request@v6 29 | with: 30 | token: ${{ secrets.GITHUB_TOKEN }} 31 | branch: issue/${{ github.event.issue.number }}-toc-entry 32 | delete-branch: true 33 | commit-message: Add command from issue #${{ github.event.issue.number }} 34 | title: Add command from issue #${{ github.event.issue.number }} 35 | body: | 36 | ## Summary 37 | - Generated from issue #${{ github.event.issue.number }} using the Git command submission template. 38 | - Adds a new entry to `toc-source.json`. 39 | -------------------------------------------------------------------------------- /contents/cleanup-branches-fast.md: -------------------------------------------------------------------------------- 1 | [⬅️ Back to Table of Contents](https://github.com/mike-rambil/Advanced-Git/blob/main/README.md#cleanup-branches-fast) 2 | 3 | # Cleanup Branches Fast ⚡ 4 | 5 | 6 | ![Category: Branch Management](https://img.shields.io/badge/Category-Branch%20Management-blue) 7 | > Quickly view and clean up local branches using Bash or PowerShell, including removing branches whose remote is gone. 8 | 9 | 10 | #### ProTips 11 | > [!TIP] 12 | > Run 'git fetch -p' before cleaning up branches to update remote info. 13 | 14 | > [!TIP] 15 | > Always double-check which branches will be deleted. 16 | 17 | 18 | ## Key Topics & Subcommands 19 | - [Delete Local Branches Whose Remote is Gone (Bash)](./delete-local-branches-whose-remote-is-gone-bash.md): Delete all local branches whose remote counterpart has been deleted, using Bash. 20 | - [Delete Local Branches Whose Remote is Gone (PowerShell)](./delete-local-branches-whose-remote-is-gone-powershell.md): Delete all local branches whose remote counterpart has been deleted, using PowerShell. 21 | - [View and Clean Up Local Git Branches (Bash)](./view-and-clean-up-local-git-branches-bash.md): Scripts to view and clean up local branches using Bash. 22 | - [View and Clean Up Local Git Branches (PowerShell)](./view-and-clean-up-local-git-branches-powershell.md): Scripts to view and clean up local branches using PowerShell. 23 | 24 | 25 | [➡️ Continue to Next Topic: Git Command Reference (Full List)](https://github.com/mike-rambil/Advanced-Git/blob/main/contents/git-command-reference-full-list.md) 26 | 27 | --- 28 | 29 | _Author: mike-rambil • Updated: 2024-06-10 • Tags: branches, cleanup, fast, bash, powershell_ 30 | -------------------------------------------------------------------------------- /contents/create-patch-from-last-commit-s.md: -------------------------------------------------------------------------------- 1 | [⬅️ Back to Sharing Changes as Patch Files](https://github.com/mike-rambil/Advanced-Git/blob/main/contents/sharing-changes-as-patch-files.md) 2 | 3 | # Create Patch from Last Commit(s) 4 | 5 | 6 | ![Category: Patch & Diff](https://img.shields.io/badge/Category-Patch%20%26%20Diff-blue) 7 | 8 | #### Command 9 | ```sh 10 | git format-patch HEAD~1 11 | ``` 12 | 13 | #### Examples 14 | - **Create a .patch file for the last commit.** 15 | 16 | ```sh 17 | git format-patch HEAD~1 18 | ``` 19 | - **Create a single patch file for all commits on top of main.** 20 | 21 | ```sh 22 | git format-patch origin/main..HEAD --stdout > my-changes.patch 23 | ``` 24 | - **Create patch files for the last two commits.** 25 | 26 | ```sh 27 | git format-patch -2 28 | ``` 29 | - **Create patch files for all commits since main.** 30 | 31 | ```sh 32 | git format-patch -2 origin/main..HEAD 33 | ``` 34 | 35 | 36 | #### Steps 37 | 1. Run '`git format-patch HEAD~1' to create a patch for the last commit`. 38 | 2. Use '`git format-patch origin/main..HEAD --stdout > my-changes.patch' to create a single patch file for multiple commits`. 39 | 40 | 41 | #### Warnings 42 | - ⚠️ Patch files created this way include commit messages, authorship, and timestamps. 43 | - ⚠️ Use 'git am' to apply these patches on another system. 44 | 45 | 46 | #### Links 47 | - [Official Docs](https://git-scm.com/docs/git-format-patch) 48 | 49 | 50 | [➡️ See the Next Step: Apply Patch with Commit Metadata](https://github.com/mike-rambil/Advanced-Git/blob/main/contents/apply-patch-with-commit-metadata.md) 51 | 52 | --- 53 | 54 | _Author: mike-rambil • Updated: 2024-06-10 • Tags: patch, format-patch, committed_ 55 | -------------------------------------------------------------------------------- /contents/how-to-use-git-push-force-with-lease-safely.md: -------------------------------------------------------------------------------- 1 | [⬅️ Back to Table of Contents](https://github.com/mike-rambil/Advanced-Git/blob/main/README.md#how-to-use-git-push-force-with-lease-safely) 2 | 3 | # How to Use git push --force-with-lease Safely 4 | 5 | 6 | ![Category: Collaboration](https://img.shields.io/badge/Category-Collaboration-blue) 7 | > Safely force-push to a branch without overwriting others' work. 8 | 9 | Guide to using `git push --force-with-lease` to avoid overwriting others' work when force-pushing. 10 | 11 | 12 | #### Command 13 | ```sh 14 | git push --force-with-lease 15 | ``` 16 | 17 | #### Examples 18 | - **Safely force-push your changes.** 19 | 20 | ```sh 21 | git push --force-with-lease 22 | ``` 23 | - **Force-push a specific branch with lease protection.** 24 | 25 | ```sh 26 | git push --force-with-lease origin feature-branch 27 | ``` 28 | 29 | 30 | #### Steps 31 | 1. Fetch the latest changes: `git fetch origin` 32 | 2. Push with lease: `git push --force-with-lease` 33 | 3. If rejected, pull and rebase: `git pull --rebase origin main` 34 | 4. Resolve conflicts, commit, and retry push 35 | 36 | 37 | #### Prerequisites 38 | - You must have permission to push to the branch. 39 | 40 | 41 | #### Warnings 42 | - ⚠️ Never use `--force` unless you are sure. Prefer `--force-with-lease`. 43 | 44 | 45 | #### Links 46 | - [Medium Article](https://medium.com/@sahilsahilbhatia/git-push-force-with-lease-vs-force-ecae72601e80) 47 | 48 | 49 | [➡️ Continue to Next Topic: Past commits of a specific file](https://github.com/mike-rambil/Advanced-Git/blob/main/contents/past-commits-of-a-specific-file.md) 50 | 51 | --- 52 | 53 | _Author: mike-rambil • Updated: 2024-06-10 • Tags: push, force, safe_ 54 | -------------------------------------------------------------------------------- /contents/view-and-clean-up-local-git-branches-bash.md: -------------------------------------------------------------------------------- 1 | [⬅️ Back to Cleanup Branches Fast ⚡](https://github.com/mike-rambil/Advanced-Git/blob/main/contents/cleanup-branches-fast.md) 2 | 3 | [⬆️ Previous Step: Delete Local Branches Whose Remote is Gone (PowerShell)](https://github.com/mike-rambil/Advanced-Git/blob/main/contents/delete-local-branches-whose-remote-is-gone-powershell.md) 4 | 5 | # View and Clean Up Local Git Branches (Bash) 6 | 7 | 8 | ![Category: Branch Management](https://img.shields.io/badge/Category-Branch%20Management-blue) 9 | > Scripts to view and clean up local branches using Bash. 10 | 11 | 12 | #### Examples 13 | - **List local branches without a remote connection.** 14 | 15 | ```sh 16 | git branch -vv | grep -E '^\s*\S+\s+[^\[]+$' 17 | ``` 18 | - **Delete local branches without remote tracking.** 19 | 20 | ```sh 21 | git branch -vv | grep -E '^\s*\S+\s+[^\[]+$' | awk '{print $1}' | xargs git branch -D 22 | ``` 23 | - **List branches whose remote is gone.** 24 | 25 | ```sh 26 | git branch -vv | grep 'gone' 27 | ``` 28 | 29 | 30 | #### Steps 31 | 1. List local branches. 32 | 2. Delete local branches without remote. 33 | 3. View branches with deleted remote. 34 | 4. Delete stale local branches. 35 | 36 | 37 | #### Warnings 38 | - ⚠️ Deleting branches is irreversible. Double-check before running destructive commands. 39 | 40 | 41 | #### ProTips 42 | > [!TIP] 43 | > Use 'git branch -vv' to see tracking info for all branches. 44 | 45 | > [!TIP] 46 | > Pipe to 'awk' and 'xargs' for batch deletion. 47 | 48 | 49 | 50 | [➡️ See the Next Step: View and Clean Up Local Git Branches (PowerShell)](https://github.com/mike-rambil/Advanced-Git/blob/main/contents/view-and-clean-up-local-git-branches-powershell.md) 51 | 52 | --- 53 | 54 | _Author: mike-rambil • Updated: 2024-06-10 • Tags: branches, cleanup, bash_ 55 | -------------------------------------------------------------------------------- /contents/view-and-clean-up-local-git-branches-powershell.md: -------------------------------------------------------------------------------- 1 | [⬅️ Back to Cleanup Branches Fast ⚡](https://github.com/mike-rambil/Advanced-Git/blob/main/contents/cleanup-branches-fast.md) 2 | 3 | [⬆️ Previous Step: View and Clean Up Local Git Branches (Bash)](https://github.com/mike-rambil/Advanced-Git/blob/main/contents/view-and-clean-up-local-git-branches-bash.md) 4 | 5 | # View and Clean Up Local Git Branches (PowerShell) 6 | 7 | 8 | ![Category: Branch Management](https://img.shields.io/badge/Category-Branch%20Management-blue) 9 | > Scripts to view and clean up local branches using PowerShell. 10 | 11 | 12 | #### Examples 13 | - **List local branches without a remote connection.** 14 | 15 | ```sh 16 | git branch -vv | Select-String -NotMatch "origin/" 17 | ``` 18 | - **Delete local branches without remote tracking.** 19 | 20 | ```sh 21 | git branch -vv | Select-String -NotMatch "origin/" | ForEach-Object { $branch = ($_ -split "\s+")[1]; git branch -D $branch } 22 | ``` 23 | - **List branches whose remote is gone.** 24 | 25 | ```sh 26 | git branch -vv | Select-String 'gone' 27 | ``` 28 | 29 | 30 | #### Steps 31 | 1. List local branches. 32 | 2. Delete local branches without remote. 33 | 3. View branches with deleted remote. 34 | 4. Delete stale local branches. 35 | 36 | 37 | #### Warnings 38 | - ⚠️ Deleting branches is irreversible. Double-check before running destructive commands. 39 | 40 | 41 | #### ProTips 42 | > [!TIP] 43 | > Use PowerShell's 'Select-String' for flexible filtering. 44 | 45 | > [!TIP] 46 | > Automate cleanup with a script for regular maintenance. 47 | 48 | 49 | 50 | [➡️ Continue to Next Topic: Git Command Reference (Full List)](https://github.com/mike-rambil/Advanced-Git/blob/main/contents/git-command-reference-full-list.md) 51 | 52 | --- 53 | 54 | _Author: mike-rambil • Updated: 2024-06-10 • Tags: branches, cleanup, powershell_ 55 | -------------------------------------------------------------------------------- /contents/delete-local-branches-whose-remote-is-gone-bash.md: -------------------------------------------------------------------------------- 1 | [⬅️ Back to Cleanup Branches Fast ⚡](https://github.com/mike-rambil/Advanced-Git/blob/main/contents/cleanup-branches-fast.md) 2 | 3 | # Delete Local Branches Whose Remote is Gone (Bash) 4 | 5 | 6 | ![Category: Branch Management](https://img.shields.io/badge/Category-Branch%20Management-blue) 7 | > Delete all local branches whose remote counterpart has been deleted, using Bash. 8 | 9 | This command fetches the latest remote info and deletes all local branches whose remote tracking branch no longer exists (marked as 'gone'). Useful for cleaning up after remote branch deletions. 10 | 11 | 12 | #### Command 13 | ```sh 14 | git fetch -p && git branch -vv | grep '\[origin/.*: gone\]' | awk '{print $1}' | xargs -r git branch -d 15 | ``` 16 | 17 | #### Examples 18 | - **Delete all local branches whose remote is gone.** 19 | 20 | ```sh 21 | git fetch -p && git branch -vv | grep '\[origin/.*: gone\]' | awk '{print $1}' | xargs -r git branch -d 22 | ``` 23 | - **Delete only feature branches whose remote is gone.** 24 | 25 | ```sh 26 | git fetch -p && git branch -vv | grep '\[origin/feature: gone\]' | awk '{print $1}' | xargs -r git branch -d 27 | ``` 28 | 29 | 30 | #### Steps 31 | 1. Fetch latest remote info: `git fetch -p` 32 | 2. List local branches whose remote is gone: `git branch -vv | grep '[origin/.*: gone`]' 33 | 3. Delete those branches: ... | awk '{print $1}' | xargs -r `git branch -d` 34 | 35 | 36 | #### Warnings 37 | - ⚠️ This will permanently delete local branches. Double-check before running. 38 | - ⚠️ Make sure you have no unmerged work on these branches. 39 | 40 | 41 | #### ProTips 42 | > [!TIP] 43 | > Use this after deleting branches on the remote to keep your local repo tidy. 44 | 45 | > [!TIP] 46 | > Add 'echo' before 'git branch -d' to preview what will be deleted. 47 | 48 | 49 | 50 | [➡️ See the Next Step: Delete Local Branches Whose Remote is Gone (PowerShell)](https://github.com/mike-rambil/Advanced-Git/blob/main/contents/delete-local-branches-whose-remote-is-gone-powershell.md) 51 | 52 | --- 53 | 54 | _Author: mike-rambil • Updated: 2024-06-10 • Tags: branches, cleanup, gone, bash_ 55 | -------------------------------------------------------------------------------- /contents/git-maintenance-start.md: -------------------------------------------------------------------------------- 1 | [⬅️ Back to Git Essentials & Hidden Gems](https://github.com/mike-rambil/Advanced-Git/blob/main/contents/git-essentials-hidden-gems.md) 2 | 3 | # git maintenance start 4 | 5 | 6 | ![Category: Maintenance](https://img.shields.io/badge/Category-Maintenance-blue) 7 | > Runs a cronJob in background for the specified repo for periodic maintenance. 8 | 9 | `git maintenance start` enables background maintenance tasks for your Git repository. It sets up scheduled jobs (using your system’s scheduler, like cron on Unix or Task Scheduler on Windows) to automatically run Git maintenance commands at regular intervals. This keeps your repository fast and healthy by running tasks like garbage collection, commit-graph optimization, and cleanup operations in the background, so you don’t have to remember to do it manually. 10 | 11 | 12 | #### Command 13 | ```sh 14 | git maintenance start 15 | ``` 16 | 17 | #### Examples 18 | - **Enable background maintenance for your repository.** 19 | 20 | ```sh 21 | git maintenance start 22 | ``` 23 | - **Run maintenance tasks every hour for more active repos.** 24 | 25 | ```sh 26 | git maintenance start --schedule=hourly 27 | ``` 28 | 29 | 30 | #### Steps 31 | 1. Run `git maintenance start` in your repository. 32 | 2. Optionally, use `--schedule=hourly` or `--schedule=daily` to control how often maintenance runs. 33 | 3. `Git will now automatically run tasks like garbage collection, pruning unreachable objects, and optimizing internal data structures in the background`. 34 | 4. You can stop background maintenance with `git maintenance stop` if needed. 35 | 36 | 37 | #### ProTips 38 | > [!TIP] 39 | > Set up maintenance on large or long-lived repos to keep them fast and healthy. 40 | 41 | > [!TIP] 42 | > Use with cron or scheduled tasks for automation. 43 | 44 | > [!TIP] 45 | > If you notice Git getting slow, check if maintenance is enabled or run it manually. 46 | 47 | 48 | 49 | #### Links 50 | - [Official Docs](https://git-scm.com/docs/git-maintenance) 51 | 52 | 53 | [➡️ See the Next Step: git request-pull](https://github.com/mike-rambil/Advanced-Git/blob/main/contents/git-request-pull.md) 54 | 55 | --- 56 | 57 | _Author: mike-rambil • Updated: 2024-06-10 • Tags: maintenance, automation_ 58 | -------------------------------------------------------------------------------- /contents/delete-local-branches-whose-remote-is-gone-powershell.md: -------------------------------------------------------------------------------- 1 | [⬅️ Back to Cleanup Branches Fast ⚡](https://github.com/mike-rambil/Advanced-Git/blob/main/contents/cleanup-branches-fast.md) 2 | 3 | [⬆️ Previous Step: Delete Local Branches Whose Remote is Gone (Bash)](https://github.com/mike-rambil/Advanced-Git/blob/main/contents/delete-local-branches-whose-remote-is-gone-bash.md) 4 | 5 | # Delete Local Branches Whose Remote is Gone (PowerShell) 6 | 7 | 8 | ![Category: Branch Management](https://img.shields.io/badge/Category-Branch%20Management-blue) 9 | > Delete all local branches whose remote counterpart has been deleted, using PowerShell. 10 | 11 | This script fetches the latest remote info and deletes all local branches whose remote tracking branch no longer exists (marked as 'gone'). Useful for cleaning up after remote branch deletions. 12 | 13 | 14 | #### Command 15 | ```sh 16 | git fetch -p 17 | git branch -vv | ForEach-Object { if ($_ -match '\[.*: gone\]') { $parts = $_.Trim() -split '\s+'; $branch = $parts[0]; if ($branch -ne '') { git branch -d $branch } } } 18 | ``` 19 | 20 | #### Examples 21 | - **Delete all local branches whose remote is gone.** 22 | 23 | ```sh 24 | git fetch -p 25 | git branch -vv | ForEach-Object { if ($_ -match '[.*: gone]') { $parts = $_.Trim() -split '\s+'; $branch = $parts[0]; if ($branch -ne '') { git branch -d $branch } } } 26 | ``` 27 | - **Delete only feature branches whose remote is gone.** 28 | 29 | ```sh 30 | git fetch -p 31 | git branch -vv | ForEach-Object { if ($_ -match '[origin/feature: gone]') { $parts = $_.Trim() -split 's+'; $branch = $parts[0]; if ($branch -ne '') { git branch -d $branch } } } 32 | ``` 33 | 34 | 35 | #### Steps 36 | 1. Fetch latest remote info: `git fetch -p` 37 | 2. List local branches whose remote is gone: `git branch -vv | ForEach-Object { if ($_ -match '[.*: gone`]') ... } 38 | 3. Delete those branches inside the loop. 39 | 40 | 41 | #### Warnings 42 | - ⚠️ This will permanently delete local branches. Double-check before running. 43 | - ⚠️ Make sure you have no unmerged work on these branches. 44 | 45 | 46 | #### ProTips 47 | > [!TIP] 48 | > Great for Windows users to automate branch cleanup. 49 | 50 | > [!TIP] 51 | > Review the list before confirming deletion. 52 | 53 | 54 | 55 | [➡️ See the Next Step: View and Clean Up Local Git Branches (Bash)](https://github.com/mike-rambil/Advanced-Git/blob/main/contents/view-and-clean-up-local-git-branches-bash.md) 56 | 57 | --- 58 | 59 | _Author: mike-rambil • Updated: 2024-06-10 • Tags: branches, cleanup, gone, powershell_ 60 | -------------------------------------------------------------------------------- /contents/git-clean-remove-untracked-files-and-directories.md: -------------------------------------------------------------------------------- 1 | [⬅️ Back to Table of Contents](https://github.com/mike-rambil/Advanced-Git/blob/main/README.md#git-clean-remove-untracked-files-and-directories) 2 | 3 | # Git Clean: Remove Untracked Files and Directories 4 | 5 | 6 | ![Category: Stashing and Cleaning](https://img.shields.io/badge/Category-Stashing%20and%20Cleaning-blue) 7 | > Remove untracked files and directories from your repository. 8 | 9 | `git clean` is a powerful command that helps remove untracked files and directories from your repository. It is particularly useful when you want to reset your working directory without affecting committed files. 10 | 11 | 12 | #### Command 13 | ```sh 14 | git clean 15 | ``` 16 | 17 | #### Flags 18 | - `-n`: Shows what will be deleted without actually deleting anything. 19 | - `-f`: Forces deletion of untracked files. 20 | - `-d`: Deletes untracked directories. 21 | - `-i`: Interactive mode to selectively delete files. 22 | - `-x`: Removes ignored and untracked files. 23 | - `-X`: Removes only ignored files. 24 | 25 | 26 | #### Examples 27 | - **Preview what will be deleted (dry run).** 28 | 29 | ```sh 30 | git clean -n -d 31 | ``` 32 | - **Delete all untracked files.** 33 | 34 | ```sh 35 | git clean -f 36 | ``` 37 | - **Delete all untracked files and directories.** 38 | 39 | ```sh 40 | git clean -f -d 41 | ``` 42 | - **Interactive mode for selective deletion.** 43 | 44 | ```sh 45 | git clean -i 46 | ``` 47 | - **Delete untracked and ignored files.** 48 | 49 | ```sh 50 | git clean -f -x 51 | ``` 52 | 53 | 54 | #### Steps 55 | 1. Preview deletions: `git clean -n -d` 56 | 2. Delete untracked files: `git clean -f` 57 | 3. Delete untracked files and directories: `git clean -f -d` 58 | 4. Interactive deletion: `git clean -i` 59 | 5. Remove ignored and untracked files: `git clean -f -x` 60 | 6. Remove only ignored files: `git clean -f -X` 61 | 62 | 63 | #### Prerequisites 64 | - Make sure you have committed all important changes. 65 | 66 | 67 | #### Warnings 68 | - ⚠️ This will permanently delete files! Always use `-n` before `-f`. 69 | - ⚠️ Be cautious with `-x` and `-X` as they remove ignored files, which might include config files. 70 | 71 | 72 | #### Links 73 | - [Official Docs](https://git-scm.com/docs/git-clean) 74 | 75 | 76 | [➡️ Continue to Next Topic: How to Use git worktree Safely](https://github.com/mike-rambil/Advanced-Git/blob/main/contents/how-to-use-git-worktree-safely.md) 77 | 78 | --- 79 | 80 | _Author: mike-rambil • Updated: 2024-06-10 • Tags: clean, untracked, workspace_ 81 | -------------------------------------------------------------------------------- /contents/git-request-pull.md: -------------------------------------------------------------------------------- 1 | [⬅️ Back to Git Essentials & Hidden Gems](https://github.com/mike-rambil/Advanced-Git/blob/main/contents/git-essentials-hidden-gems.md) 2 | 3 | [⬆️ Previous Step: git maintenance start](https://github.com/mike-rambil/Advanced-Git/blob/main/contents/git-maintenance-start.md) 4 | 5 | # git request-pull 6 | 7 | 8 | ![Category: Collaboration](https://img.shields.io/badge/Category-Collaboration-blue) 9 | > Generate a request to pull changes into a repository. 10 | 11 | `git request-pull` generates a summary message describing the changes between two commits, which you can send to a project maintainer to request that they pull your changes. This is especially useful for email-based workflows or when collaborating outside of platforms like GitHub. The command outputs a message that includes a comparison summary, a list of commits, and their messages, making it easy for maintainers to review and apply your changes. 12 | 13 | 14 | #### Command 15 | ```sh 16 | git request-pull 17 | ``` 18 | 19 | #### Examples 20 | - **Generates a summary like:** 21 | 22 | ```sh 23 | 24 | 25 | The following changes since commit 1234567... (main): 26 | 27 | Some previous commit message 28 | 29 | are available in the Git repository at: 30 | 31 | https://github.com/example/repo.git feature-branch 32 | 33 | for you to fetch changes up to 89abcde... (feature-branch): 34 | 35 | New feature commit message 36 | Another commit message 37 | 38 | ---------------------------------------------------------------- 39 | file1.txt | 10 ++++++++++ 40 | file2.js | 5 +++++ 41 | 2 files changed, 15 insertions(+) 42 | 43 | ``` 44 | - **Generate a pull request message from v1.0 to v1.1.** 45 | 46 | ```sh 47 | git request-pull v1.0 https://github.com/example/repo.git v1.1 48 | ``` 49 | - **Request a pull for a feature branch based on main.** 50 | 51 | ```sh 52 | git request-pull main https://github.com/example/repo.git feature-branch 53 | ``` 54 | 55 | 56 | #### Steps 57 | 1. Identify the base commit or branch you want to compare from (e.g., main or v1.0). 58 | 2. Run `git request-pull ` to generate a pull request message. 59 | 3. Send the generated message to the project maintainer (e.g., via email or chat). 60 | 61 | 62 | #### ProTips 63 | > [!TIP] 64 | > Use this command when collaborating via email or outside of web-based platforms. 65 | 66 | > [!TIP] 67 | > Include a clear start and end point for clarity. 68 | 69 | > [!TIP] 70 | > Review the generated message before sending to ensure it accurately describes your changes. 71 | 72 | 73 | 74 | #### Links 75 | - [Official Docs](https://git-scm.com/docs/git-request-pull) 76 | 77 | 78 | [➡️ Continue to Next Topic: Cleanup Branches Fast ⚡](https://github.com/mike-rambil/Advanced-Git/blob/main/contents/cleanup-branches-fast.md) 79 | 80 | --- 81 | 82 | _Author: mike-rambil • Updated: 2024-06-10 • Tags: collaboration, pull-request_ 83 | -------------------------------------------------------------------------------- /contents/pull-changes-of-specific-files-from-a-commit.md: -------------------------------------------------------------------------------- 1 | [⬅️ Back to Table of Contents](https://github.com/mike-rambil/Advanced-Git/blob/main/README.md#pull-changes-of-specific-files-from-a-commit) 2 | 3 | # Pull Changes of Specific Files from a Commit 4 | 5 | 6 | ![Category: Selective File Restore](https://img.shields.io/badge/Category-Selective%20File%20Restore-blue) 7 | > Restore or pull changes for specific files from a past commit without reverting the entire commit. 8 | 9 | How to use git to pull or restore changes for only certain files from a specific commit, without affecting the rest of your working directory or reverting the whole commit. Useful for cherry-picking file-level changes. 10 | 11 | 12 | #### Command 13 | ```sh 14 | git checkout -- 15 | ``` 16 | 17 | #### Examples 18 | - **Restore file1.txt and file2.txt from the specified commit.** 19 | 20 | ```sh 21 | git checkout e8ab7f64fdfcc7bdaaed8d96c0ac26dce035663f -- path/to/file1.txt path/to/file2.txt 22 | ``` 23 | - **Stage, commit, and push the restored files to a new branch.** 24 | 25 | ```sh 26 | git add path/to/file1.txt path/to/file2.txt 27 | git commit -m "Pulled changes for file1.txt and file2.txt from commit e8ab7f64" 28 | git push origin revert/productionOrder 29 | ``` 30 | - **Restore files using the newer 'git restore' command.** 31 | 32 | ```sh 33 | git restore --source e8ab7f64fdfcc7bdaaed8d96c0ac26dce035663f path/to/file1.txt path/to/file2.txt 34 | ``` 35 | 36 | 37 | #### Steps 38 | 1. Checkout the specific files from the desired commit using '`git checkout -- '. 39 | 2. Stage the changes with '`git add '. 40 | 3. Commit the changes with a descriptive message. 41 | 4. Push your branch and create a pull request if needed. 42 | 43 | 44 | #### Warnings 45 | - ⚠️ This will overwrite the current working directory versions of the specified files. 46 | - ⚠️ Make sure to commit or stash any local changes to those files before running the command. 47 | 48 | 49 | #### Links 50 | - [Git Docs: git checkout](https://git-scm.com/docs/git-checkout) 51 | 52 | 53 | --- 54 | 55 | ## 🎉 Congratulations! 56 | 57 | You've reached the end of this comprehensive Git guide! You've learned some of the most advanced Git techniques and commands. 58 | 59 | **What's next?** 60 | - [📚 Explore more Git topics in the main guide](https://github.com/mike-rambil/Advanced-Git/blob/main/README.md) 61 | - 🚀 **Great Git contributors put everything into practice** - if you discovered something useful or have your own Git tips, consider contributing to this repository! 62 | - 💡 Found a bug or have suggestions? [Open an issue or submit a PR](https://github.com/mike-rambil/Advanced-Git/blob/main/README.md#contributors--credits) 63 | 64 | [🏠 Back to Main README](https://github.com/mike-rambil/Advanced-Git/blob/main/README.md) 65 | 66 | --- 67 | 68 | _Author: mike-rambil • Updated: 2024-06-10 • Tags: checkout, restore, file, commit, cherry-pick_ 69 | -------------------------------------------------------------------------------- /dev-docs/FORMAT.md: -------------------------------------------------------------------------------- 1 | # Contribution Format Guide 2 | 3 | > **Purpose:** 4 | > This file defines the required format for documenting Git commands in this repository. All contributors should follow this structure when adding or updating entries in `toc-source.json`. 5 | > 6 | > **How to Contribute:** 7 | > 8 | > - When you want to add a new Git command or script, copy the template below and fill in each field as described. 9 | > - Place your new entry in `toc-source.json` using this format. 10 | > - Submit your changes via a Pull Request (PR). 11 | > - Well-formatted contributions make it easy to generate documentation and keep the project organized. 12 | > 13 | > **Where to Find This:** 14 | > 15 | > - This file: `dev-docs/FORMAT.md` (always up to date) 16 | > - Main documentation and contribution guidelines may also reference this file. 17 | 18 | --- 19 | 20 | # Format for Documenting Git Commands (JSON-Compatible) 21 | 22 | This project uses a structured format for documenting Git commands, which is stored in [`../toc-source.json`](../toc-source.json). Use the following template for each command: 23 | 24 | --- 25 | 26 | ## Name 27 | 28 | - **Type:** string 29 | - **Description:** The official name/title of the command or script. 30 | 31 | ## Category 32 | 33 | - **Type:** string 34 | - **Description:** The category this command belongs to (e.g., Collaboration, History, Worktree). 35 | 36 | ## Short Description 37 | 38 | - **Type:** string 39 | - **Description:** A concise summary of what the command does. 40 | 41 | ## Long Description 42 | 43 | - **Type:** string (optional) 44 | - **Description:** A more detailed explanation of the command, its context, and use cases. 45 | 46 | ## Command 47 | 48 | - **Type:** string (optional) 49 | - **Description:** The full command syntax, including placeholders for arguments. 50 | 51 | ## Examples 52 | 53 | - **Type:** list of objects 54 | - **Each object:** 55 | - `code`: string (the command as used) 56 | - `description`: string (what the example does) 57 | 58 | ## Steps 59 | 60 | - **Type:** list of strings 61 | - **Description:** Step-by-step instructions for using the command. 62 | 63 | ## Flags 64 | 65 | - **Type:** object (optional) 66 | - **Each key:** flag (e.g., `-f`, `-d`) 67 | - **Each value:** string (description of the flag) 68 | 69 | ## Prerequisites 70 | 71 | - **Type:** list of strings (optional) 72 | - **Description:** Requirements before using the command. 73 | 74 | ## Warnings 75 | 76 | - **Type:** list of strings (optional) 77 | - **Description:** Important cautions or risks. 78 | 79 | ## ProTips 80 | 81 | - **Type:** list of strings (optional) 82 | - **Description:** Short, actionable tips to help users be more successful with this command. Use 1–2 lines per tip. Example: "Use `-n` for a dry run before deleting files." 83 | 84 | ## Tags 85 | 86 | - **Type:** list of strings 87 | - **Description:** Keywords for search and categorization. 88 | 89 | ## Author 90 | 91 | - **Type:** string 92 | - **Description:** Who contributed this entry. 93 | 94 | ## Last Updated 95 | 96 | - **Type:** string (date) 97 | - **Description:** Last update date (YYYY-MM-DD). 98 | 99 | ## Links 100 | 101 | - **Type:** list of objects (optional) 102 | - **Each object:** 103 | - `label`: string (e.g., "Official Docs") 104 | - `url`: string (link to resource) 105 | 106 | ## Related Commands 107 | 108 | - **Type:** list of strings (optional) 109 | - **Description:** Other commands related to this one. 110 | 111 | --- 112 | 113 | ### Example Entry (Markdown) 114 | 115 | ## git clean 116 | 117 | **Category:** Stashing and Cleaning 118 | **Short Description:** Remove untracked files and directories from your repository. 119 | **Long Description:** `git clean` is a powerful command that helps remove untracked files and directories from your repository. It is particularly useful when you want to reset your working directory without affecting committed files. 120 | **Command:** `git clean` 121 | 122 | **Examples:** 123 | 124 | - `git clean -n -d` — Preview what will be deleted (dry run). 125 | - `git clean -f` — Delete all untracked files. 126 | 127 | **Steps:** 128 | 129 | 1. Preview deletions: `git clean -n -d` 130 | 2. Delete untracked files: `git clean -f` 131 | 3. Delete untracked files and directories: `git clean -f -d` 132 | 133 | **Flags:** 134 | 135 | - `-n`: Shows what will be deleted without actually deleting anything. 136 | - `-f`: Forces deletion of untracked files. 137 | - `-d`: Deletes untracked directories. 138 | - `-i`: Interactive mode to selectively delete files. 139 | - `-x`: Removes ignored and untracked files. 140 | - `-X`: Removes only ignored files. 141 | 142 | **Prerequisites:** 143 | 144 | - Make sure you have committed all important changes. 145 | 146 | **Warnings:** 147 | 148 | - This will permanently delete files! Always use `-n` before `-f`. 149 | - Be cautious with `-x` and `-X` as they remove ignored files, which might include config files. 150 | 151 | **ProTips:** 152 | 153 | - Use `git clean -n` to preview what will be deleted before running with `-f`. 154 | - Combine with `-d` to also remove untracked directories. 155 | 156 | **Tags:** clean, untracked, workspace 157 | **Author:** mike-rambil 158 | **Last Updated:** 2024-06-10 159 | 160 | **Links:** 161 | 162 | - [Official Docs](https://git-scm.com/docs/git-clean) 163 | 164 | **Related Commands:** 165 | 166 | - `git status` 167 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |
2 | banner 3 |
4 | 5 | > [!IMPORTANT] 6 | > If you find a useful GIT command - be sure to send a PR here as well :) 7 | > Refer to [contribution format guide](./dev-docs/FORMAT.md) to send a PR. 8 | 9 | # Table of Contents 10 | 11 | - [Git Essentials & Hidden Gems](./contents/git-essentials-hidden-gems.md): Start here to discover commands that can improve your workflow and understanding of Git. 12 | - [git maintenance start](./contents/git-maintenance-start.md): Runs a cronJob in background for the specified repo for periodic maintenance. 13 | - [git request-pull](./contents/git-request-pull.md): Generate a request to pull changes into a repository. 14 | - [Cleanup Branches Fast ⚡](./contents/cleanup-branches-fast.md): Quickly view and clean up local branches using Bash or PowerShell, including removing branches whose remote is gone. 15 | - [Delete Local Branches Whose Remote is Gone (Bash)](./contents/delete-local-branches-whose-remote-is-gone-bash.md): Delete all local branches whose remote counterpart has been deleted, using Bash. 16 | - [Delete Local Branches Whose Remote is Gone (PowerShell)](./contents/delete-local-branches-whose-remote-is-gone-powershell.md): Delete all local branches whose remote counterpart has been deleted, using PowerShell. 17 | - [View and Clean Up Local Git Branches (Bash)](./contents/view-and-clean-up-local-git-branches-bash.md): Scripts to view and clean up local branches using Bash. 18 | - [View and Clean Up Local Git Branches (PowerShell)](./contents/view-and-clean-up-local-git-branches-powershell.md): Scripts to view and clean up local branches using PowerShell. 19 | - [Git Command Reference (Full List)](./contents/git-command-reference-full-list.md): A comprehensive list of Git commands used in this project. 20 | - [git init --bare](./contents/git-init-bare.md): Initialize a bare repository, typically used for remote repositories. 21 | - [git clone --mirror ](./contents/git-clone-mirror-repository.md): Clone a repository in mirror mode, including all refs and branches. 22 | - [Useful Rare Git Commands You Never Heard Of](./contents/useful-rare-git-commands-you-never-heard-of.md): A collection of lesser-known but powerful Git commands. 23 | - [git replace ](./contents/git-replace-old-commit-new-commit.md): Temporarily substitute one commit for another. 24 | - [How to Use git push --force-with-lease Safely](./contents/how-to-use-git-push-force-with-lease-safely.md): Safely force-push to a branch without overwriting others' work. 25 | - [Past commits of a specific file](./contents/past-commits-of-a-specific-file.md): See all commits and changes for a specific file. 26 | - [Show Commit History of a Specific File](./contents/show-commit-history-of-a-specific-file.md) 27 | - [Show Detailed Commit History (With Changes)](./contents/show-detailed-commit-history-with-changes.md) 28 | - [Show Commit History With Author and Date](./contents/show-commit-history-with-author-and-date.md) 29 | - [See Who Last Modified Each Line (Blame)](./contents/see-who-last-modified-each-line-blame.md) 30 | - [Git Clean: Remove Untracked Files and Directories](./contents/git-clean-remove-untracked-files-and-directories.md): Remove untracked files and directories from your repository. 31 | - [How to Use git worktree Safely](./contents/how-to-use-git-worktree-safely.md): Work on multiple branches simultaneously without switching. 32 | - [Check Existing Worktrees](./contents/check-existing-worktrees.md) 33 | - [Create a New Worktree](./contents/create-a-new-worktree.md) 34 | - [Remove a Worktree](./contents/remove-a-worktree.md) 35 | - [Switch Between Worktrees](./contents/switch-between-worktrees.md) 36 | - [Use Worktrees for Temporary Fixes](./contents/use-worktrees-for-temporary-fixes.md) 37 | - [Flags and Their Uses](./contents/flags-and-their-uses.md) 38 | - [Sharing Changes as Patch Files](./contents/sharing-changes-as-patch-files.md): Generate and share patch files for committed or uncommitted changes. 39 | - [Create Patch from Last Commit(s)](./contents/create-patch-from-last-commit-s.md) 40 | - [Apply Patch with Commit Metadata](./contents/apply-patch-with-commit-metadata.md) 41 | - [Create Patch from Uncommitted Changes](./contents/create-patch-from-uncommitted-changes.md) 42 | - [Apply Diff File](./contents/apply-diff-file.md) 43 | - [Patch vs Diff: Quick Reference](./contents/patch-vs-diff-quick-reference.md) 44 | - [Pull Changes of Specific Files from a Commit](./contents/pull-changes-of-specific-files-from-a-commit.md): Restore or pull changes for specific files from a past commit without reverting the entire commit. 45 | 46 | 47 | 48 | ## Growing thanks to you ❤️ 49 | 50 | [![Stargazers over time](https://starchart.cc/mike-rambil/Advanced-Git.svg?variant=adaptive)](https://starchart.cc/mike-rambil/Advanced-Git) 51 | 52 | ## Contributors & Credits 53 | 54 | > [!NOTE] 55 | > Want to contribute? Be a contributor or author by following the [Contribution Format Guide](./dev-docs/FORMAT.md) , also add your favorite resources in [References & Resources](./CONTRIBUTING.md#references-resources) and submit a Pull Request. 56 | 57 | #### [👨‍👩‍👧‍👦 Contributors](./CONTRIBUTING.md) 58 | 59 | A list of individuals who have contributed to this project. Add your name and link in [CONTRIBUTING.md](./CONTRIBUTING.md#contributors). Please follow the instructions from [FORMAT.md](./dev-docs/FORMAT.md) when contributing. 60 | 61 | 62 | 63 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/command-submission.yml: -------------------------------------------------------------------------------- 1 | name: "Git Command Submission" 2 | description: "Submit a new Git command entry using the required format from dev-docs/FORMAT.md." 3 | title: "Add: " 4 | labels: 5 | - "new command" 6 | body: 7 | - type: markdown 8 | attributes: 9 | value: | 10 | # Contribution Format Guide 11 | 12 | **Purpose:** This template captures the required format for documenting Git commands in this repository. All contributors should follow this structure when adding or updating entries in `toc-source.json`. 13 | 14 | **How to Contribute:** 15 | 16 | - When you want to add a new Git command or script, copy the template below and fill in each field as described. 17 | - Place your new entry in `toc-source.json` using this format. 18 | - Submit your changes via a Pull Request (PR). 19 | - Well-formatted contributions make it easy to generate documentation and keep the project organized. 20 | 21 | **Where to Find This:** 22 | 23 | - This template reflects `dev-docs/FORMAT.md` (always up to date). 24 | - Main documentation and contribution guidelines may also reference this file. 25 | - type: input 26 | id: name 27 | attributes: 28 | label: "Name" 29 | placeholder: "git example-command" 30 | description: | 31 | Type: string 32 | Description: The official name/title of the command or script. 33 | validations: 34 | required: true 35 | - type: input 36 | id: category 37 | attributes: 38 | label: "Category" 39 | placeholder: "History" 40 | description: | 41 | Type: string 42 | Description: The category this command belongs to (e.g., Collaboration, History, Worktree). 43 | validations: 44 | required: true 45 | - type: input 46 | id: short_description 47 | attributes: 48 | label: "Short Description" 49 | placeholder: "Summarize what the command does." 50 | description: | 51 | Type: string 52 | Description: A concise summary of what the command does. 53 | validations: 54 | required: true 55 | - type: textarea 56 | id: long_description 57 | attributes: 58 | label: "Long Description" 59 | description: | 60 | Type: string (optional) 61 | Description: A more detailed explanation of the command, its context, and use cases. 62 | Please provide plain text or Markdown. 63 | placeholder: "Explain when and why to use this command..." 64 | validations: 65 | required: false 66 | - type: input 67 | id: command 68 | attributes: 69 | label: "Command" 70 | description: | 71 | Type: string (optional) 72 | Description: The full command syntax, including placeholders for arguments. 73 | placeholder: "git example-command " 74 | validations: 75 | required: false 76 | - type: textarea 77 | id: examples 78 | attributes: 79 | label: "Examples" 80 | description: | 81 | Type: list of objects 82 | Each object: 83 | - `code`: string (the command as used) 84 | - `description`: string (what the example does) 85 | Provide as valid JSON. Example: 86 | [ 87 | { 88 | "code": "git clean -n -d", 89 | "description": "Preview what will be deleted (dry run)." 90 | } 91 | ] 92 | validations: 93 | required: true 94 | - type: textarea 95 | id: steps 96 | attributes: 97 | label: "Steps" 98 | description: | 99 | Type: list of strings 100 | Description: Step-by-step instructions for using the command. 101 | Provide as a JSON array of strings. 102 | placeholder: | 103 | [ 104 | "First step...", 105 | "Second step..." 106 | ] 107 | validations: 108 | required: true 109 | - type: textarea 110 | id: flags 111 | attributes: 112 | label: "Flags" 113 | description: | 114 | Type: object (optional) 115 | Each key: flag (e.g., `-f`, `-d`) 116 | Each value: string (description of the flag) 117 | Provide as a JSON object. 118 | placeholder: | 119 | { 120 | "-f": "Forces the action." 121 | } 122 | validations: 123 | required: false 124 | - type: textarea 125 | id: prerequisites 126 | attributes: 127 | label: "Prerequisites" 128 | description: | 129 | Type: list of strings (optional) 130 | Description: Requirements before using the command. 131 | Provide as a JSON array of strings. 132 | placeholder: | 133 | [ 134 | "Have a clean working tree." 135 | ] 136 | validations: 137 | required: false 138 | - type: textarea 139 | id: warnings 140 | attributes: 141 | label: "Warnings" 142 | description: | 143 | Type: list of strings (optional) 144 | Description: Important cautions or risks. 145 | Provide as a JSON array of strings. 146 | placeholder: | 147 | [ 148 | "This will permanently delete files." 149 | ] 150 | validations: 151 | required: false 152 | - type: textarea 153 | id: protips 154 | attributes: 155 | label: "ProTips" 156 | description: | 157 | Type: list of strings (optional) 158 | Description: Short, actionable tips to help users be more successful with this command. Use 1–2 lines per tip. 159 | Provide as a JSON array of strings. 160 | placeholder: | 161 | [ 162 | "Use `-n` for a dry run before deleting files." 163 | ] 164 | validations: 165 | required: false 166 | - type: textarea 167 | id: tags 168 | attributes: 169 | label: "Tags" 170 | description: | 171 | Type: list of strings 172 | Description: Keywords for search and categorization. 173 | Provide as a JSON array of strings. 174 | placeholder: | 175 | [ 176 | "clean", 177 | "workspace" 178 | ] 179 | validations: 180 | required: true 181 | - type: input 182 | id: author 183 | attributes: 184 | label: "Author" 185 | description: | 186 | Type: string 187 | Description: Who contributed this entry. 188 | placeholder: "your-github-handle" 189 | validations: 190 | required: true 191 | - type: input 192 | id: last_updated 193 | attributes: 194 | label: "Last Updated" 195 | description: | 196 | Type: string (date) 197 | Description: Last update date (YYYY-MM-DD). 198 | placeholder: "2025-10-14" 199 | validations: 200 | required: true 201 | - type: textarea 202 | id: links 203 | attributes: 204 | label: "Links" 205 | description: | 206 | Type: list of objects (optional) 207 | Each object: 208 | - `label`: string (e.g., \"Official Docs\") 209 | - `url`: string (link to resource) 210 | Provide as valid JSON. 211 | placeholder: | 212 | [ 213 | { 214 | "label": "Official Docs", 215 | "url": "https://git-scm.com/docs/git-clean" 216 | } 217 | ] 218 | validations: 219 | required: false 220 | - type: textarea 221 | id: related_commands 222 | attributes: 223 | label: "Related Commands" 224 | description: | 225 | Type: list of strings (optional) 226 | Description: Other commands related to this one. 227 | Provide as a JSON array of strings. 228 | placeholder: | 229 | [ 230 | "git status" 231 | ] 232 | validations: 233 | required: false 234 | -------------------------------------------------------------------------------- /scripts/issue-to-toc.js: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 3 | const fs = require("fs"); 4 | const path = require("path"); 5 | 6 | const ISSUE_BODY = process.env.ISSUE_BODY; 7 | const ISSUE_NUMBER = process.env.ISSUE_NUMBER || "unknown"; 8 | const WORKSPACE = process.env.GITHUB_WORKSPACE || process.cwd(); 9 | 10 | if (!ISSUE_BODY) { 11 | console.error("ISSUE_BODY environment variable is required."); 12 | process.exit(1); 13 | } 14 | 15 | const FIELD_CONFIG = [ 16 | { heading: "Name", key: "Name", required: true, parser: asString }, 17 | { heading: "Category", key: "category", required: true, parser: asString }, 18 | { 19 | heading: "Short Description", 20 | key: "short_description", 21 | required: true, 22 | parser: asString, 23 | }, 24 | { 25 | heading: "Long Description", 26 | key: "long_description", 27 | required: false, 28 | parser: asOptionalString, 29 | }, 30 | { heading: "Command", key: "command", required: false, parser: asOptionalString }, 31 | { 32 | heading: "Examples", 33 | key: "examples", 34 | required: true, 35 | parser: asExamples, 36 | }, 37 | { 38 | heading: "Steps", 39 | key: "steps", 40 | required: true, 41 | parser: asStringArray, 42 | }, 43 | { heading: "Flags", key: "flags", required: false, parser: asFlags }, 44 | { 45 | heading: "Prerequisites", 46 | key: "prerequisites", 47 | required: false, 48 | parser: asOptionalStringArray, 49 | }, 50 | { 51 | heading: "Warnings", 52 | key: "warnings", 53 | required: false, 54 | parser: asOptionalStringArray, 55 | }, 56 | { 57 | heading: "ProTips", 58 | key: "protips", 59 | required: false, 60 | parser: asOptionalStringArray, 61 | }, 62 | { 63 | heading: "Tags", 64 | key: "tags", 65 | required: true, 66 | parser: asStringArray, 67 | }, 68 | { heading: "Author", key: "author", required: true, parser: asString }, 69 | { 70 | heading: "Last Updated", 71 | key: "last_updated", 72 | required: true, 73 | parser: asDateString, 74 | }, 75 | { heading: "Links", key: "links", required: false, parser: asLinks }, 76 | { 77 | heading: "Related Commands", 78 | key: "related_commands", 79 | required: false, 80 | parser: asOptionalStringArray, 81 | }, 82 | ]; 83 | 84 | const sections = parseSections(ISSUE_BODY); 85 | const entry = {}; 86 | 87 | for (const field of FIELD_CONFIG) { 88 | const rawValue = sections[field.heading] ?? ""; 89 | if (!rawValue && field.required) { 90 | fail(`Field "${field.heading}" is required but was not provided.`); 91 | } 92 | const parsedValue = field.parser(rawValue, field.heading); 93 | if (parsedValue !== undefined) { 94 | entry[field.key] = parsedValue; 95 | } 96 | } 97 | 98 | const tocPath = path.join(WORKSPACE, "toc-source.json"); 99 | const toc = readJson(tocPath); 100 | ensureUniqueName(entry.Name, toc); 101 | toc.push(entry); 102 | writeJson(tocPath, toc); 103 | 104 | console.log(`Entry for "${entry.Name}" added to toc-source.json from issue #${ISSUE_NUMBER}.`); 105 | 106 | function parseSections(body) { 107 | const normalized = body.replace(/\r\n/g, "\n").trim(); 108 | const regex = /### ([^\n]+)\n([\s\S]*?)(?=(?:\n### [^\n]+)|$)/g; 109 | const result = {}; 110 | let match; 111 | while ((match = regex.exec(normalized)) !== null) { 112 | const heading = match[1].trim(); 113 | const value = match[2] ?? ""; 114 | result[heading] = value; 115 | } 116 | return result; 117 | } 118 | 119 | function cleanupValue(value) { 120 | if (!value) return ""; 121 | let cleaned = value.trim(); 122 | const isNoResponse = (text) => 123 | text.replace(/\s+/g, " ").toLowerCase() === "_no response_"; 124 | if (isNoResponse(cleaned)) { 125 | return ""; 126 | } 127 | if (cleaned.startsWith("```")) { 128 | const lines = cleaned.split(/\r?\n/); 129 | if (lines[0].startsWith("```")) { 130 | lines.shift(); 131 | const last = lines[lines.length - 1]; 132 | if (last && last.startsWith("```")) { 133 | lines.pop(); 134 | } 135 | cleaned = lines.join("\n").trim(); 136 | if (isNoResponse(cleaned)) { 137 | return ""; 138 | } 139 | } 140 | } 141 | return cleaned; 142 | } 143 | 144 | function asString(raw, field) { 145 | const value = cleanupValue(raw); 146 | if (!value) { 147 | fail(`Field "${field}" must be a non-empty string.`); 148 | } 149 | return value; 150 | } 151 | 152 | function asOptionalString(raw) { 153 | const value = cleanupValue(raw); 154 | return value ? value : undefined; 155 | } 156 | 157 | function asDateString(raw, field) { 158 | const value = asString(raw, field); 159 | if (!/^\d{4}-\d{2}-\d{2}$/.test(value)) { 160 | fail(`Field "${field}" must follow the YYYY-MM-DD format.`); 161 | } 162 | return value; 163 | } 164 | 165 | function parseJson(raw, field) { 166 | const value = cleanupValue(raw); 167 | if (!value) { 168 | return undefined; 169 | } 170 | try { 171 | return JSON.parse(value); 172 | } catch (error) { 173 | fail(`Field "${field}" must contain valid JSON. ${error.message}`); 174 | } 175 | } 176 | 177 | function asStringArray(raw, field) { 178 | const parsed = parseJson(raw, field); 179 | if (!Array.isArray(parsed) || parsed.length === 0) { 180 | fail(`Field "${field}" must be a non-empty JSON array of strings.`); 181 | } 182 | parsed.forEach((item, index) => { 183 | if (typeof item !== "string" || !item.trim()) { 184 | fail(`Field "${field}" must contain only non-empty strings (problem at index ${index}).`); 185 | } 186 | }); 187 | return parsed; 188 | } 189 | 190 | function asOptionalStringArray(raw, field) { 191 | const value = cleanupValue(raw); 192 | if (!value) { 193 | return undefined; 194 | } 195 | const parsed = parseJson(value, field); 196 | if (!Array.isArray(parsed)) { 197 | fail(`Field "${field}" must be a JSON array of strings.`); 198 | } 199 | parsed.forEach((item, index) => { 200 | if (typeof item !== "string" || !item.trim()) { 201 | fail(`Field "${field}" must contain only non-empty strings (problem at index ${index}).`); 202 | } 203 | }); 204 | return parsed; 205 | } 206 | 207 | function asExamples(raw, field) { 208 | const parsed = parseJson(raw, field); 209 | if (!Array.isArray(parsed) || parsed.length === 0) { 210 | fail(`Field "${field}" must be a non-empty JSON array of objects with "code" and "description" strings.`); 211 | } 212 | parsed.forEach((item, index) => { 213 | if (!item || typeof item !== "object") { 214 | fail(`Field "${field}" must contain objects (problem at index ${index}).`); 215 | } 216 | if (typeof item.code !== "string" || !item.code.trim()) { 217 | fail(`Field "${field}" example ${index} is missing a non-empty "code" string.`); 218 | } 219 | if (typeof item.description !== "string" || !item.description.trim()) { 220 | fail(`Field "${field}" example ${index} is missing a non-empty "description" string.`); 221 | } 222 | }); 223 | return parsed; 224 | } 225 | 226 | function asFlags(raw, field) { 227 | const value = cleanupValue(raw); 228 | if (!value) { 229 | return undefined; 230 | } 231 | const parsed = parseJson(value, field); 232 | if (!parsed || Array.isArray(parsed) || typeof parsed !== "object") { 233 | fail(`Field "${field}" must be a JSON object of flag descriptions.`); 234 | } 235 | Object.entries(parsed).forEach(([flag, description]) => { 236 | if (typeof flag !== "string" || !flag.trim()) { 237 | fail(`Field "${field}" contains a flag with an invalid name.`); 238 | } 239 | if (typeof description !== "string" || !description.trim()) { 240 | fail(`Field "${field}" flag "${flag}" must have a non-empty description string.`); 241 | } 242 | }); 243 | return parsed; 244 | } 245 | 246 | function asLinks(raw, field) { 247 | const value = cleanupValue(raw); 248 | if (!value) { 249 | return undefined; 250 | } 251 | const parsed = parseJson(value, field); 252 | if (!Array.isArray(parsed)) { 253 | fail(`Field "${field}" must be a JSON array of link objects.`); 254 | } 255 | parsed.forEach((item, index) => { 256 | if (!item || typeof item !== "object") { 257 | fail(`Field "${field}" must contain objects (problem at index ${index}).`); 258 | } 259 | if (typeof item.label !== "string" || !item.label.trim()) { 260 | fail(`Field "${field}" link ${index} is missing a non-empty "label" string.`); 261 | } 262 | if (typeof item.url !== "string" || !item.url.trim()) { 263 | fail(`Field "${field}" link ${index} is missing a non-empty "url" string.`); 264 | } 265 | }); 266 | return parsed; 267 | } 268 | 269 | function ensureUniqueName(name, toc) { 270 | const exists = toc.some((entry) => { 271 | if (entry && typeof entry === "object") { 272 | if (entry.Name === name) return true; 273 | if (Array.isArray(entry.subtoc)) { 274 | return entry.subtoc.some((sub) => sub && sub.Name === name); 275 | } 276 | } 277 | return false; 278 | }); 279 | if (exists) { 280 | fail(`An entry with the Name "${name}" already exists in toc-source.json.`); 281 | } 282 | } 283 | 284 | function readJson(filePath) { 285 | try { 286 | const raw = fs.readFileSync(filePath, "utf8"); 287 | return JSON.parse(raw); 288 | } catch (error) { 289 | fail(`Unable to read or parse JSON file at ${filePath}. ${error.message}`); 290 | } 291 | } 292 | 293 | function writeJson(filePath, data) { 294 | const serialized = JSON.stringify(data, null, 2) + "\n"; 295 | fs.writeFileSync(filePath, serialized, "utf8"); 296 | } 297 | 298 | function fail(message) { 299 | console.error(message); 300 | process.exit(1); 301 | } 302 | -------------------------------------------------------------------------------- /scripts/generate-readme.js: -------------------------------------------------------------------------------- 1 | const fs = require('fs'); 2 | const path = require('path'); 3 | 4 | // --- CONFIG --- 5 | const GITHUB_REPO_URL = 'https://github.com/mike-rambil/Advanced-Git'; 6 | const GITHUB_BRANCH = 'main'; 7 | const GITHUB_CONTENTS_URL = `${GITHUB_REPO_URL}/blob/${GITHUB_BRANCH}/contents`; 8 | const GITHUB_README_URL = `${GITHUB_REPO_URL}/blob/${GITHUB_BRANCH}/README.md`; 9 | const GITHUB_PR_URL = `${GITHUB_REPO_URL}/pulls`; 10 | const INTRO = `
11 | banner 12 |
13 | 14 | > [!IMPORTANT] 15 | > If you find a useful GIT command - be sure to send a PR here as well :) 16 | > Refer to [contribution format guide](./dev-docs/FORMAT.md) to send a PR. 17 | `; 18 | 19 | const TOC_HEADER = '# Table of Contents'; 20 | 21 | const CONCLUSION = ` 22 | ## Contributors & Credits 23 | 24 | > [!NOTE] 25 | > Want to contribute? Be a contributor or author by following the [Contribution Format Guide](./dev-docs/FORMAT.md) , also add your favorite resources in [References & Resources](./CONTRIBUTING.md#references-resources) and submit a Pull Request. 26 | 27 | #### [👨‍👩‍👧‍👦 Contributors](./CONTRIBUTING.md) 28 | 29 | A list of individuals who have contributed to this project. Add your name and link in [CONTRIBUTING.md](./CONTRIBUTING.md#contributors). Please follow the instructions from [FORMAT.md](./dev-docs/FORMAT.md) when contributing. 30 | `; 31 | 32 | const TOC_JSON = path.join(__dirname, '..', 'toc-source.json'); 33 | const CONTENTS_DIR = path.join(__dirname, '..', 'contents'); 34 | const README = path.join(__dirname, '..', 'README.md'); 35 | 36 | // Ensure the contents directory exists 37 | fs.mkdirSync(CONTENTS_DIR, { recursive: true }); 38 | 39 | function tocEntry(obj, idx) { 40 | let entry = `- [${obj.Name}](./contents/${slugify(obj.Name)}.md)`; 41 | if (obj.short_description) entry += `: ${obj.short_description}`; 42 | if (obj.subtoc && obj.subtoc.length) { 43 | entry += '\n'; 44 | obj.subtoc.forEach((sub) => { 45 | entry += ` - [${sub.Name}](./contents/${slugify(sub.Name)}.md)`; 46 | if (sub.short_description) entry += `: ${sub.short_description}`; 47 | entry += '\n'; 48 | }); 49 | } else { 50 | entry += '\n'; 51 | } 52 | return entry; 53 | } 54 | 55 | function slugify(str) { 56 | return str 57 | .toLowerCase() 58 | .replace(/[^a-z0-9]+/g, '-') 59 | .replace(/(^-|-$)/g, ''); 60 | } 61 | 62 | function renderSection(title, content) { 63 | return content ? `\n#### ${title}\n${content}\n` : ''; 64 | } 65 | 66 | function renderFlags(flags) { 67 | if (!flags || Object.keys(flags).length === 0) return ''; 68 | let out = ''; 69 | Object.entries(flags).forEach(([flag, desc]) => { 70 | out += `- \`${flag}\`: ${desc}\n`; 71 | }); 72 | return renderSection('Flags', out); 73 | } 74 | 75 | function renderSteps(steps) { 76 | if (!steps || !steps.length) return ''; 77 | let out = ''; 78 | steps.forEach((step, i) => { 79 | // If the step is just a command, render as a code block 80 | if (/^git [^\n]+$/.test(step.trim())) { 81 | out += `${i + 1}.\n \`\`\`sh\n${step.trim()}\n\`\`\`\n`; 82 | } else { 83 | // Otherwise, wrap inline commands in backticks 84 | out += `${i + 1}. ${step.replace( 85 | /(`[^`]+`|\bgit [^ ]+[^\n]*\b)/gi, 86 | (match) => (match.startsWith('`') ? match : '`' + match + '`') 87 | )}\n`; 88 | } 89 | }); 90 | return renderSection('Steps', out); 91 | } 92 | 93 | function renderExamples(examples) { 94 | if (!examples || !examples.length) return ''; 95 | let out = ''; 96 | examples.forEach((ex) => { 97 | out += `- **${ex.description || ''}** \n\n \`\`\`sh\n${ 98 | ex.code 99 | } \n \`\`\`\n`; 100 | }); 101 | return renderSection('Examples', out); 102 | } 103 | 104 | function renderLinks(links) { 105 | if (!links || !links.length) return ''; 106 | let out = ''; 107 | links.forEach((link) => { 108 | out += `- [${link.label}](${link.url})\n`; 109 | }); 110 | return renderSection('Links', out); 111 | } 112 | 113 | function renderPrerequisites(prereq) { 114 | if (!prereq || !prereq.length) return ''; 115 | let out = ''; 116 | prereq.forEach((p) => { 117 | out += `- ${p}\n`; 118 | }); 119 | return renderSection('Prerequisites', out); 120 | } 121 | 122 | function renderWarnings(warnings) { 123 | if (!warnings || !warnings.length) return ''; 124 | let out = ''; 125 | warnings.forEach((w) => { 126 | out += `- ⚠️ ${w}\n`; 127 | }); 128 | return renderSection('Warnings', out); 129 | } 130 | 131 | function renderProTips(protips) { 132 | if (!protips || !protips.length) return ''; 133 | let out = ''; 134 | protips.forEach((tip) => { 135 | out += `> [!TIP]\n> ${tip}\n\n`; 136 | }); 137 | return renderSection('ProTips', out); 138 | } 139 | 140 | function renderTags(tags) { 141 | if (!tags || !tags.length) return ''; 142 | return renderSection('Tags', tags.map((t) => `\`${t}\``).join(', ')); 143 | } 144 | 145 | function renderRelatedCommands(related) { 146 | if (!related || !related.length) return ''; 147 | let out = ''; 148 | related.forEach((cmd) => { 149 | out += `- ${cmd}\n`; 150 | }); 151 | return renderSection('Related Commands', out); 152 | } 153 | 154 | function renderOutputExample(output) { 155 | if (!output) return ''; 156 | return renderSection('Output Example', `\`\`\`${output}\`\`\``); 157 | } 158 | 159 | function renderAuthor(author) { 160 | if (!author) return ''; 161 | return renderSection('Author', author); 162 | } 163 | 164 | function renderLastUpdated(date) { 165 | if (!date) return ''; 166 | return renderSection('Last Updated', date); 167 | } 168 | 169 | function renderCategory(category) { 170 | if (!category) return ''; 171 | const badge = `![Category: ${category}](https://img.shields.io/badge/Category-${encodeURIComponent( 172 | category 173 | )}-blue)`; 174 | return `\n${badge}\n`; 175 | } 176 | 177 | function renderCommandExamples(examples) { 178 | if (!examples || !examples.length) return ''; 179 | let out = ''; 180 | examples.forEach((cmd) => { 181 | out += `- \`${cmd}\`\n`; 182 | }); 183 | return renderSection('Similar Examples', out); 184 | } 185 | 186 | function renderCommand(command) { 187 | if (!command) return ''; 188 | // Render as a code block if it looks like a command 189 | if (/^git /.test(command)) { 190 | return '\n#### Command\n```sh\n' + command + '\n```\n'; 191 | } else { 192 | return '\n#### Command\n`' + command + '`\n'; 193 | } 194 | } 195 | 196 | function conciseMetaLine(author, lastUpdated, tags) { 197 | let meta = []; 198 | if (author) meta.push(`Author: ${author}`); 199 | if (lastUpdated) meta.push(`Updated: ${lastUpdated}`); 200 | if (tags && tags.length) meta.push(`Tags: ${tags.join(', ')}`); 201 | return meta.length ? `\n---\n\n_${meta.join(' • ')}_\n` : ''; 202 | } 203 | 204 | function generateMiniSubtocTOC(obj) { 205 | if (!obj.subtoc || !obj.subtoc.length) return ''; 206 | let out = '## Key Topics & Subcommands\n'; 207 | obj.subtoc.forEach((sub) => { 208 | out += `- [${sub.Name}](./${slugify(sub.Name)}.md)`; 209 | if (sub.short_description) out += `: ${sub.short_description}`; 210 | out += '\n'; 211 | }); 212 | return out + '\n'; 213 | } 214 | 215 | function generateContentFile(obj, idx, tocData) { 216 | let slug = slugify(obj.Name); 217 | let md = `[⬅️ Back to Table of Contents](${GITHUB_README_URL}#${slug})\n\n`; 218 | md += `# ${obj.Name}\n\n`; 219 | if (obj.category) md += renderCategory(obj.category); 220 | if (obj.short_description) md += `> ${obj.short_description}\n\n`; 221 | 222 | if (obj.long_description) md += `${obj.long_description}\n\n`; 223 | if (obj.command) md += renderCommand(obj.command); 224 | if (obj.flags) md += renderFlags(obj.flags); 225 | if (obj.examples) md += renderExamples(obj.examples); 226 | if (obj['command similiar examples']) 227 | md += renderCommandExamples(obj['command similiar examples']); 228 | if (obj.steps) md += renderSteps(obj.steps); 229 | if (obj.prerequisites) md += renderPrerequisites(obj.prerequisites); 230 | if (obj.warnings) md += renderWarnings(obj.warnings); 231 | if (obj.protips) md += renderProTips(obj.protips); 232 | if (obj.links) md += renderLinks(obj.links); 233 | if (obj.related_commands) md += renderRelatedCommands(obj.related_commands); 234 | if (obj.output_example) md += renderOutputExample(obj.output_example); 235 | 236 | // Always add mini-TOC if subtoc exists 237 | if (obj.subtoc && obj.subtoc.length) { 238 | md += generateMiniSubtocTOC(obj); 239 | } 240 | 241 | // Navigation logic for main TOC items 242 | if (idx < tocData.length - 1) { 243 | // There's a next main TOC item 244 | const nextMainToc = tocData[idx + 1]; 245 | md += `\n[➡️ Continue to Next Topic: ${ 246 | nextMainToc.Name 247 | }](${GITHUB_CONTENTS_URL}/${slugify(nextMainToc.Name)}.md)\n`; 248 | } else { 249 | // This is the very last page - show congratulations 250 | md += `\n---\n\n## 🎉 Congratulations!\n\nYou've reached the end of this comprehensive Git guide! You've learned some of the most advanced Git techniques and commands.\n\n**What's next?**\n- [📚 Explore more Git topics in the main guide](${GITHUB_README_URL})\n- 🚀 **Great Git contributors put everything into practice** - if you discovered something useful or have your own Git tips, consider contributing to this repository!\n- 💡 Found a bug or have suggestions? [Open an issue or submit a PR](${GITHUB_README_URL}#contributors--credits)\n\n[🏠 Back to Main README](${GITHUB_README_URL})\n`; 251 | } 252 | 253 | md += conciseMetaLine(obj.author, obj.last_updated, obj.tags); 254 | return md; 255 | } 256 | 257 | function writeIfChanged(filePath, content) { 258 | if (fs.existsSync(filePath)) { 259 | const existing = fs.readFileSync(filePath, 'utf8'); 260 | if (existing === content) return; // No change 261 | } 262 | fs.writeFileSync(filePath, content, 'utf8'); 263 | } 264 | 265 | function generateSubtocFile(obj, idx, tocData) { 266 | obj.subtoc.forEach((sub, subIdx) => { 267 | const subPath = path.join(CONTENTS_DIR, `${slugify(sub.Name)}.md`); 268 | let subMd = ''; 269 | // Always add Back to parent 270 | subMd += `[⬅️ Back to ${obj.Name}](${GITHUB_CONTENTS_URL}/${slugify( 271 | obj.Name 272 | )}.md)\n\n`; 273 | if (subIdx > 0) { 274 | const prev = obj.subtoc[subIdx - 1]; 275 | subMd += `[⬆️ Previous Step: ${ 276 | prev.Name 277 | }](${GITHUB_CONTENTS_URL}/${slugify(prev.Name)}.md)\n\n`; 278 | } 279 | subMd += `# ${sub.Name}\n\n`; 280 | if (sub.category) subMd += renderCategory(sub.category); 281 | if (sub.short_description) subMd += `> ${sub.short_description}\n\n`; 282 | if (sub.long_description) subMd += `${sub.long_description}\n\n`; 283 | if (sub.command) subMd += renderCommand(sub.command); 284 | if (sub.flags) subMd += renderFlags(sub.flags); 285 | if (sub.examples) subMd += renderExamples(sub.examples); 286 | if (sub.steps) subMd += renderSteps(sub.steps); 287 | if (sub.prerequisites) subMd += renderPrerequisites(sub.prerequisites); 288 | if (sub.warnings) subMd += renderWarnings(sub.warnings); 289 | if (sub.protips) subMd += renderProTips(sub.protips); 290 | if (sub.links) subMd += renderLinks(sub.links); 291 | if (sub.related_commands) 292 | subMd += renderRelatedCommands(sub.related_commands); 293 | if (sub.output_example) subMd += renderOutputExample(sub.output_example); 294 | 295 | // Navigation logic 296 | if (subIdx < obj.subtoc.length - 1) { 297 | // Not the last subtoc, link to next subtoc 298 | const next = obj.subtoc[subIdx + 1]; 299 | subMd += `\n[➡️ See the Next Step: ${ 300 | next.Name 301 | }](${GITHUB_CONTENTS_URL}/${slugify(next.Name)}.md)\n`; 302 | } else { 303 | // This is the last subtoc, check if there's a next main TOC item 304 | if (idx < tocData.length - 1) { 305 | // There's a next main TOC item 306 | const nextMainToc = tocData[idx + 1]; 307 | subMd += `\n[➡️ Continue to Next Topic: ${ 308 | nextMainToc.Name 309 | }](${GITHUB_CONTENTS_URL}/${slugify(nextMainToc.Name)}.md)\n`; 310 | } else { 311 | // This is the very last page - show congratulations 312 | subMd += `\n---\n\n## 🎉 Congratulations!\n\nYou've reached the end of this comprehensive Git guide! You've learned some of the most advanced Git techniques and commands.\n\n**What's next?**\n- [📚 Explore more Git topics in the main guide](${GITHUB_README_URL})\n- 🚀 **Great Git contributors put everything into practice** - if you discovered something useful or have your own Git tips, consider contributing to this repository!\n- 💡 Found a bug or have suggestions? [Open an issue or submit a PR](${GITHUB_README_URL}#contributors--credits)\n\n[🏠 Back to Main README](${GITHUB_README_URL})\n`; 313 | } 314 | } 315 | 316 | subMd += conciseMetaLine(sub.author, sub.last_updated, sub.tags); 317 | writeIfChanged(subPath, subMd); 318 | }); 319 | } 320 | 321 | function main() { 322 | const tocData = JSON.parse(fs.readFileSync(TOC_JSON, 'utf8')); 323 | 324 | // Generate TOC 325 | let toc = ''; 326 | tocData.forEach((obj, idx) => { 327 | toc += tocEntry(obj, idx); 328 | }); 329 | 330 | // Write README.md (always overwrite) 331 | const readmeContent = `${INTRO}\n${TOC_HEADER}\n\n${toc}\n${CONCLUSION}`; 332 | fs.writeFileSync(README, readmeContent, 'utf8'); 333 | 334 | // Write/Update content files only if changed 335 | tocData.forEach((obj, idx) => { 336 | const filePath = path.join(CONTENTS_DIR, `${slugify(obj.Name)}.md`); 337 | const content = generateContentFile(obj, idx, tocData); 338 | writeIfChanged(filePath, content); 339 | // Also create subtoc files if needed 340 | if (obj.subtoc && obj.subtoc.length) { 341 | generateSubtocFile(obj, idx, tocData); 342 | } 343 | }); 344 | console.log('Markdown files updated with improved formatting.'); 345 | } 346 | 347 | main(); 348 | -------------------------------------------------------------------------------- /toc-source.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "Name": "Git Essentials & Hidden Gems", 4 | "category": "Miscellaneous", 5 | "short_description": "Start here to discover commands that can improve your workflow and understanding of Git.", 6 | "long_description": "A collection of practical, lesser-known, and foundational Git commands that are useful for all users. Start here to discover commands that can improve your workflow and understanding of Git.", 7 | "tags": ["misc", "cleanup", "advanced"], 8 | "author": "mike-rambil", 9 | "last_updated": "2024-06-10", 10 | "protips": [ 11 | "Try these commands in a test repo before using them on important projects.", 12 | "Bookmark this section for quick reference to hidden gems." 13 | ], 14 | "subtoc": [ 15 | { 16 | "Name": "git maintenance start", 17 | "category": "Maintenance", 18 | "short_description": "Runs a cronJob in background for the specified repo for periodic maintenance.", 19 | "long_description": "`git maintenance start` enables background maintenance tasks for your Git repository. It sets up scheduled jobs (using your system’s scheduler, like cron on Unix or Task Scheduler on Windows) to automatically run Git maintenance commands at regular intervals. This keeps your repository fast and healthy by running tasks like garbage collection, commit-graph optimization, and cleanup operations in the background, so you don’t have to remember to do it manually.", 20 | "command": "git maintenance start", 21 | "examples": [ 22 | { 23 | "code": "git maintenance start", 24 | "description": "Enable background maintenance for your repository." 25 | }, 26 | { 27 | "code": "git maintenance start --schedule=hourly", 28 | "description": "Run maintenance tasks every hour for more active repos." 29 | } 30 | ], 31 | "steps": [ 32 | "Run `git maintenance start` in your repository.", 33 | "Optionally, use `--schedule=hourly` or `--schedule=daily` to control how often maintenance runs.", 34 | "Git will now automatically run tasks like garbage collection, pruning unreachable objects, and optimizing internal data structures in the background.", 35 | "You can stop background maintenance with `git maintenance stop` if needed." 36 | ], 37 | "links": [ 38 | { 39 | "label": "Official Docs", 40 | "url": "https://git-scm.com/docs/git-maintenance" 41 | } 42 | ], 43 | "tags": ["maintenance", "automation"], 44 | "author": "mike-rambil", 45 | "last_updated": "2024-06-10", 46 | "protips": [ 47 | "Set up maintenance on large or long-lived repos to keep them fast and healthy.", 48 | "Use with cron or scheduled tasks for automation.", 49 | "If you notice Git getting slow, check if maintenance is enabled or run it manually." 50 | ] 51 | }, 52 | { 53 | "Name": "git request-pull", 54 | "category": "Collaboration", 55 | "short_description": "Generate a request to pull changes into a repository.", 56 | "long_description": "`git request-pull` generates a summary message describing the changes between two commits, which you can send to a project maintainer to request that they pull your changes. This is especially useful for email-based workflows or when collaborating outside of platforms like GitHub. The command outputs a message that includes a comparison summary, a list of commits, and their messages, making it easy for maintainers to review and apply your changes.", 57 | "command": "git request-pull ", 58 | "examples": [ 59 | { 60 | "code": "\n\nThe following changes since commit 1234567... (main):\n\n Some previous commit message\n\nare available in the Git repository at:\n\n https://github.com/example/repo.git feature-branch\n\nfor you to fetch changes up to 89abcde... (feature-branch):\n\n New feature commit message\n Another commit message\n\n----------------------------------------------------------------\n file1.txt | 10 ++++++++++\n file2.js | 5 +++++\n 2 files changed, 15 insertions(+)\n", 61 | "description": "Generates a summary like:" 62 | }, 63 | { 64 | "code": "git request-pull v1.0 https://github.com/example/repo.git v1.1", 65 | "description": "Generate a pull request message from v1.0 to v1.1." 66 | }, 67 | { 68 | "code": "git request-pull main https://github.com/example/repo.git feature-branch", 69 | "description": "Request a pull for a feature branch based on main." 70 | } 71 | ], 72 | "steps": [ 73 | "Identify the base commit or branch you want to compare from (e.g., main or v1.0).", 74 | "Run `git request-pull ` to generate a pull request message.", 75 | "Send the generated message to the project maintainer (e.g., via email or chat)." 76 | ], 77 | "links": [ 78 | { 79 | "label": "Official Docs", 80 | "url": "https://git-scm.com/docs/git-request-pull" 81 | } 82 | ], 83 | "tags": ["collaboration", "pull-request"], 84 | "author": "mike-rambil", 85 | "last_updated": "2024-06-10", 86 | "protips": [ 87 | "Use this command when collaborating via email or outside of web-based platforms.", 88 | "Include a clear start and end point for clarity.", 89 | "Review the generated message before sending to ensure it accurately describes your changes." 90 | ] 91 | } 92 | ] 93 | }, 94 | { 95 | "Name": "Cleanup Branches Fast ⚡", 96 | "category": "Branch Management", 97 | "short_description": "Quickly view and clean up local branches using Bash or PowerShell, including removing branches whose remote is gone.", 98 | "tags": ["branches", "cleanup", "fast", "bash", "powershell"], 99 | "author": "mike-rambil", 100 | "last_updated": "2024-06-10", 101 | "protips": [ 102 | "Run 'git fetch -p' before cleaning up branches to update remote info.", 103 | "Always double-check which branches will be deleted." 104 | ], 105 | "subtoc": [ 106 | { 107 | "Name": "Delete Local Branches Whose Remote is Gone (Bash)", 108 | "category": "Branch Management", 109 | "short_description": "Delete all local branches whose remote counterpart has been deleted, using Bash.", 110 | "long_description": "This command fetches the latest remote info and deletes all local branches whose remote tracking branch no longer exists (marked as 'gone'). Useful for cleaning up after remote branch deletions.", 111 | "command": "git fetch -p && git branch -vv | grep '\\[origin/.*: gone\\]' | awk '{print $1}' | xargs -r git branch -d", 112 | "examples": [ 113 | { 114 | "code": "git fetch -p && git branch -vv | grep '\\[origin/.*: gone\\]' | awk '{print $1}' | xargs -r git branch -d", 115 | "description": "Delete all local branches whose remote is gone." 116 | }, 117 | { 118 | "code": "git fetch -p && git branch -vv | grep '\\[origin/feature: gone\\]' | awk '{print $1}' | xargs -r git branch -d", 119 | "description": "Delete only feature branches whose remote is gone." 120 | } 121 | ], 122 | "steps": [ 123 | "Fetch latest remote info: git fetch -p", 124 | "List local branches whose remote is gone: git branch -vv | grep '[origin/.*: gone]'", 125 | "Delete those branches: ... | awk '{print $1}' | xargs -r git branch -d" 126 | ], 127 | "warnings": [ 128 | "This will permanently delete local branches. Double-check before running.", 129 | "Make sure you have no unmerged work on these branches." 130 | ], 131 | "tags": ["branches", "cleanup", "gone", "bash"], 132 | "author": "mike-rambil", 133 | "last_updated": "2024-06-10", 134 | "protips": [ 135 | "Use this after deleting branches on the remote to keep your local repo tidy.", 136 | "Add 'echo' before 'git branch -d' to preview what will be deleted." 137 | ] 138 | }, 139 | { 140 | "Name": "Delete Local Branches Whose Remote is Gone (PowerShell)", 141 | "category": "Branch Management", 142 | "short_description": "Delete all local branches whose remote counterpart has been deleted, using PowerShell.", 143 | "long_description": "This script fetches the latest remote info and deletes all local branches whose remote tracking branch no longer exists (marked as 'gone'). Useful for cleaning up after remote branch deletions.", 144 | "command": "git fetch -p\ngit branch -vv | ForEach-Object { if ($_ -match '\\[.*: gone\\]') { $parts = $_.Trim() -split '\\s+'; $branch = $parts[0]; if ($branch -ne '') { git branch -d $branch } } }", 145 | "examples": [ 146 | { 147 | "code": "git fetch -p\ngit branch -vv | ForEach-Object { if ($_ -match '[.*: gone]') { $parts = $_.Trim() -split '\\s+'; $branch = $parts[0]; if ($branch -ne '') { git branch -d $branch } } }", 148 | "description": "Delete all local branches whose remote is gone." 149 | }, 150 | { 151 | "code": "git fetch -p\ngit branch -vv | ForEach-Object { if ($_ -match '[origin/feature: gone]') { $parts = $_.Trim() -split 's+'; $branch = $parts[0]; if ($branch -ne '') { git branch -d $branch } } }", 152 | "description": "Delete only feature branches whose remote is gone." 153 | } 154 | ], 155 | "steps": [ 156 | "Fetch latest remote info: git fetch -p", 157 | "List local branches whose remote is gone: git branch -vv | ForEach-Object { if ($_ -match '[.*: gone]') ... }", 158 | "Delete those branches inside the loop." 159 | ], 160 | "warnings": [ 161 | "This will permanently delete local branches. Double-check before running.", 162 | "Make sure you have no unmerged work on these branches." 163 | ], 164 | "tags": ["branches", "cleanup", "gone", "powershell"], 165 | "author": "mike-rambil", 166 | "last_updated": "2024-06-10", 167 | "protips": [ 168 | "Great for Windows users to automate branch cleanup.", 169 | "Review the list before confirming deletion." 170 | ] 171 | }, 172 | { 173 | "Name": "View and Clean Up Local Git Branches (Bash)", 174 | "category": "Branch Management", 175 | "short_description": "Scripts to view and clean up local branches using Bash.", 176 | "examples": [ 177 | { 178 | "code": "git branch -vv | grep -E '^\\s*\\S+\\s+[^\\[]+$'", 179 | "description": "List local branches without a remote connection." 180 | }, 181 | { 182 | "code": "git branch -vv | grep -E '^\\s*\\S+\\s+[^\\[]+$' | awk '{print $1}' | xargs git branch -D", 183 | "description": "Delete local branches without remote tracking." 184 | }, 185 | { 186 | "code": "git branch -vv | grep 'gone'", 187 | "description": "List branches whose remote is gone." 188 | } 189 | ], 190 | "steps": [ 191 | "List local branches.", 192 | "Delete local branches without remote.", 193 | "View branches with deleted remote.", 194 | "Delete stale local branches." 195 | ], 196 | "warnings": [ 197 | "Deleting branches is irreversible. Double-check before running destructive commands." 198 | ], 199 | "tags": ["branches", "cleanup", "bash"], 200 | "author": "mike-rambil", 201 | "last_updated": "2024-06-10", 202 | "protips": [ 203 | "Use 'git branch -vv' to see tracking info for all branches.", 204 | "Pipe to 'awk' and 'xargs' for batch deletion." 205 | ] 206 | }, 207 | { 208 | "Name": "View and Clean Up Local Git Branches (PowerShell)", 209 | "category": "Branch Management", 210 | "short_description": "Scripts to view and clean up local branches using PowerShell.", 211 | "examples": [ 212 | { 213 | "code": "git branch -vv | Select-String -NotMatch \"origin/\"", 214 | "description": "List local branches without a remote connection." 215 | }, 216 | { 217 | "code": "git branch -vv | Select-String -NotMatch \"origin/\" | ForEach-Object { $branch = ($_ -split \"\\s+\")[1]; git branch -D $branch }", 218 | "description": "Delete local branches without remote tracking." 219 | }, 220 | { 221 | "code": "git branch -vv | Select-String 'gone'", 222 | "description": "List branches whose remote is gone." 223 | } 224 | ], 225 | "steps": [ 226 | "List local branches.", 227 | "Delete local branches without remote.", 228 | "View branches with deleted remote.", 229 | "Delete stale local branches." 230 | ], 231 | "warnings": [ 232 | "Deleting branches is irreversible. Double-check before running destructive commands." 233 | ], 234 | "tags": ["branches", "cleanup", "powershell"], 235 | "author": "mike-rambil", 236 | "last_updated": "2024-06-10", 237 | "protips": [ 238 | "Use PowerShell's 'Select-String' for flexible filtering.", 239 | "Automate cleanup with a script for regular maintenance." 240 | ] 241 | } 242 | ] 243 | }, 244 | { 245 | "Name": "Git Command Reference (Full List)", 246 | "category": "Reference", 247 | "short_description": "A comprehensive list of Git commands used in this project.", 248 | "long_description": "A comprehensive list of Git commands used in this project, formatted according to our standard.", 249 | "tags": ["reference", "all-commands"], 250 | "author": "mike-rambil", 251 | "last_updated": "2024-06-10", 252 | "subtoc": [ 253 | { 254 | "Name": "git init --bare", 255 | "category": "Repository Management", 256 | "short_description": "Initialize a bare repository, typically used for remote repositories.", 257 | "command": "git init --bare my-repo.git", 258 | "examples": [ 259 | { 260 | "code": "git init --bare my-repo.git", 261 | "description": "Create a bare repository for collaboration." 262 | }, 263 | { 264 | "code": "git init --bare /srv/git/project.git", 265 | "description": "Initialize a bare repo in a custom directory for server hosting." 266 | } 267 | ], 268 | "steps": [ 269 | "Run `git init --bare my-repo.git` to create a bare repository." 270 | ], 271 | "tags": ["init", "bare", "repository"], 272 | "author": "mike-rambil", 273 | "last_updated": "2024-06-10" 274 | }, 275 | { 276 | "Name": "git clone --mirror ", 277 | "category": "Repository Management", 278 | "short_description": "Clone a repository in mirror mode, including all refs and branches.", 279 | "command": "git clone --mirror https://github.com/example/repo.git", 280 | "examples": [ 281 | { 282 | "code": "git clone --mirror https://github.com/example/repo.git", 283 | "description": "Create a full backup or migration of a repository." 284 | }, 285 | { 286 | "code": "git clone --mirror git@github.com:org/repo.git", 287 | "description": "Mirror-clone a private repo using SSH." 288 | } 289 | ], 290 | "steps": [ 291 | "Run `git clone --mirror ` to create a full backup or migration." 292 | ], 293 | "tags": ["clone", "mirror", "backup"], 294 | "author": "mike-rambil", 295 | "last_updated": "2024-06-10" 296 | } 297 | ] 298 | }, 299 | { 300 | "Name": "Useful Rare Git Commands You Never Heard Of", 301 | "category": "Advanced", 302 | "short_description": "A collection of lesser-known but powerful Git commands.", 303 | "long_description": "A collection of lesser-known but powerful Git commands. Use these to level up your Git workflow!", 304 | "tags": ["rare", "advanced", "tips"], 305 | "author": "mike-rambil", 306 | "last_updated": "2024-06-10", 307 | "subtoc": [ 308 | { 309 | "Name": "git replace ", 310 | "category": "History", 311 | "short_description": "Temporarily substitute one commit for another.", 312 | "command": "git replace abc123 def456", 313 | "examples": [ 314 | { 315 | "code": "git replace abc123 def456", 316 | "description": "Temporarily replace commit abc123 with def456." 317 | }, 318 | { 319 | "code": "git replace --graft HEAD~2 HEAD", 320 | "description": "Graft a new parent onto a commit for testing history changes." 321 | } 322 | ], 323 | "steps": [ 324 | "Run `git replace ` to test or patch history." 325 | ], 326 | "tags": ["replace", "history"], 327 | "author": "mike-rambil", 328 | "last_updated": "2024-06-10" 329 | } 330 | ] 331 | }, 332 | { 333 | "Name": "How to Use git push --force-with-lease Safely", 334 | "category": "Collaboration", 335 | "short_description": "Safely force-push to a branch without overwriting others' work.", 336 | "long_description": "Guide to using `git push --force-with-lease` to avoid overwriting others' work when force-pushing.", 337 | "command": "git push --force-with-lease", 338 | "examples": [ 339 | { 340 | "code": "git push --force-with-lease", 341 | "description": "Safely force-push your changes." 342 | }, 343 | { 344 | "code": "git push --force-with-lease origin feature-branch", 345 | "description": "Force-push a specific branch with lease protection." 346 | } 347 | ], 348 | "steps": [ 349 | "Fetch the latest changes: `git fetch origin`", 350 | "Push with lease: `git push --force-with-lease`", 351 | "If rejected, pull and rebase: `git pull --rebase origin main`", 352 | "Resolve conflicts, commit, and retry push" 353 | ], 354 | "prerequisites": ["You must have permission to push to the branch."], 355 | "warnings": [ 356 | "Never use `--force` unless you are sure. Prefer `--force-with-lease`." 357 | ], 358 | "links": [ 359 | { 360 | "label": "Medium Article", 361 | "url": "https://medium.com/@sahilsahilbhatia/git-push-force-with-lease-vs-force-ecae72601e80" 362 | } 363 | ], 364 | "tags": ["push", "force", "safe"], 365 | "author": "mike-rambil", 366 | "last_updated": "2024-06-10" 367 | }, 368 | { 369 | "Name": "Past commits of a specific file", 370 | "category": "History and Inspection", 371 | "short_description": "See all commits and changes for a specific file.", 372 | "long_description": "You can see all commits related to a specific file using Git commands. Here are a few ways to do it:", 373 | "tags": ["history", "inspection", "file"], 374 | "author": "mike-rambil", 375 | "last_updated": "2024-06-10", 376 | "subtoc": [ 377 | { 378 | "Name": "Show Commit History of a Specific File", 379 | "category": "History", 380 | "command": "git log --oneline -- filename.txt", 381 | "examples": [ 382 | { 383 | "code": "git log --oneline -- filename.txt", 384 | "description": "List all commits that modified `filename.txt`." 385 | }, 386 | { 387 | "code": "git log --oneline -- path/to/anotherfile.js", 388 | "description": "Show commit history for a different file." 389 | } 390 | ], 391 | "steps": ["Lists all commits that modified `filename.txt`."], 392 | "tags": ["log", "file", "history"], 393 | "related_commands": [ 394 | "git log -p -- filename.txt", 395 | "git blame filename.txt" 396 | ], 397 | "author": "mike-rambil", 398 | "last_updated": "2024-06-10" 399 | }, 400 | { 401 | "Name": "Show Detailed Commit History (With Changes)", 402 | "category": "History", 403 | "command": "git log -p -- filename.txt", 404 | "examples": [ 405 | { 406 | "code": "git log -p -- filename.txt", 407 | "description": "Show each commit and the actual changes made to `filename.txt`." 408 | }, 409 | { 410 | "code": "git log -p -2 -- filename.txt", 411 | "description": "Show the last two commits and their changes for a file." 412 | } 413 | ], 414 | "steps": [ 415 | "Shows each commit and the actual changes made to `filename.txt`." 416 | ], 417 | "tags": ["log", "diff", "file"], 418 | "related_commands": ["git log --oneline -- filename.txt"], 419 | "author": "mike-rambil", 420 | "last_updated": "2024-06-10" 421 | }, 422 | { 423 | "Name": "Show Commit History With Author and Date", 424 | "category": "History", 425 | "command": "git log --pretty=format:\"%h - %an, %ar : %s\" -- filename.txt", 426 | "examples": [ 427 | { 428 | "code": "git log --pretty=format:\"%h - %an, %ar : %s\" -- filename.txt", 429 | "description": "Display commit hash, author, relative date, and commit message." 430 | }, 431 | { 432 | "code": "git log --pretty=format:'%h | %ad | %an | %s' --date=short -- filename.txt", 433 | "description": "Show commit hash, short date, author, and message." 434 | } 435 | ], 436 | "steps": [ 437 | "Displays commit hash, author, relative date, and commit message." 438 | ], 439 | "tags": ["log", "author", "date"], 440 | "author": "mike-rambil", 441 | "last_updated": "2024-06-10" 442 | }, 443 | { 444 | "Name": "See Who Last Modified Each Line (Blame)", 445 | "category": "History", 446 | "command": "git blame filename.txt", 447 | "examples": [ 448 | { 449 | "code": "git blame filename.txt", 450 | "description": "Show the last commit that changed each line of the file." 451 | }, 452 | { 453 | "code": "git blame -L 10,20 filename.txt", 454 | "description": "Blame only lines 10 to 20 of a file." 455 | } 456 | ], 457 | "steps": ["Shows the last commit that changed each line of the file."], 458 | "tags": ["blame", "file", "history"], 459 | "warnings": [ 460 | "Blame can be misleading if the file has been heavily refactored." 461 | ], 462 | "author": "mike-rambil", 463 | "last_updated": "2024-06-10" 464 | } 465 | ] 466 | }, 467 | { 468 | "Name": "Git Clean: Remove Untracked Files and Directories", 469 | "category": "Stashing and Cleaning", 470 | "short_description": "Remove untracked files and directories from your repository.", 471 | "long_description": "`git clean` is a powerful command that helps remove untracked files and directories from your repository. It is particularly useful when you want to reset your working directory without affecting committed files.", 472 | "command": "git clean", 473 | "flags": { 474 | "-n": "Shows what will be deleted without actually deleting anything.", 475 | "-f": "Forces deletion of untracked files.", 476 | "-d": "Deletes untracked directories.", 477 | "-i": "Interactive mode to selectively delete files.", 478 | "-x": "Removes ignored and untracked files.", 479 | "-X": "Removes only ignored files." 480 | }, 481 | "examples": [ 482 | { 483 | "code": "git clean -n -d", 484 | "description": "Preview what will be deleted (dry run)." 485 | }, 486 | { 487 | "code": "git clean -f", 488 | "description": "Delete all untracked files." 489 | }, 490 | { 491 | "code": "git clean -f -d", 492 | "description": "Delete all untracked files and directories." 493 | }, 494 | { 495 | "code": "git clean -i", 496 | "description": "Interactive mode for selective deletion." 497 | }, 498 | { 499 | "code": "git clean -f -x", 500 | "description": "Delete untracked and ignored files." 501 | } 502 | ], 503 | "steps": [ 504 | "Preview deletions: `git clean -n -d`", 505 | "Delete untracked files: `git clean -f`", 506 | "Delete untracked files and directories: `git clean -f -d`", 507 | "Interactive deletion: `git clean -i`", 508 | "Remove ignored and untracked files: `git clean -f -x`", 509 | "Remove only ignored files: `git clean -f -X`" 510 | ], 511 | "prerequisites": ["Make sure you have committed all important changes."], 512 | "warnings": [ 513 | "This will permanently delete files! Always use `-n` before `-f`.", 514 | "Be cautious with `-x` and `-X` as they remove ignored files, which might include config files." 515 | ], 516 | "links": [ 517 | { "label": "Official Docs", "url": "https://git-scm.com/docs/git-clean" } 518 | ], 519 | "tags": ["clean", "untracked", "workspace"], 520 | "author": "mike-rambil", 521 | "last_updated": "2024-06-10" 522 | }, 523 | { 524 | "Name": "How to Use git worktree Safely", 525 | "category": "Worktree", 526 | "short_description": "Work on multiple branches simultaneously without switching.", 527 | "long_description": "`git worktree` allows you to manage multiple working directories linked to a single Git repository. It helps developers work on multiple branches simultaneously without switching branches in the same directory.", 528 | "tags": ["worktree", "branches", "advanced"], 529 | "author": "mike-rambil", 530 | "last_updated": "2024-06-10", 531 | "subtoc": [ 532 | { 533 | "Name": "Check Existing Worktrees", 534 | "category": "Worktree", 535 | "command": "git worktree list", 536 | "examples": [ 537 | { 538 | "code": "git worktree list", 539 | "description": "List all active worktrees." 540 | }, 541 | { 542 | "code": "git worktree list --porcelain", 543 | "description": "List worktrees in a machine-readable format." 544 | } 545 | ], 546 | "steps": ["List all active worktrees."], 547 | "tags": ["worktree", "list"], 548 | "author": "mike-rambil", 549 | "last_updated": "2024-06-10" 550 | }, 551 | { 552 | "Name": "Create a New Worktree", 553 | "category": "Worktree", 554 | "command": "git worktree add ", 555 | "examples": [ 556 | { 557 | "code": "git worktree add ../feature-branch feature", 558 | "description": "Create a new worktree for the feature branch." 559 | }, 560 | { 561 | "code": "git worktree add ../hotfix hotfix-branch", 562 | "description": "Create a worktree for a hotfix branch." 563 | } 564 | ], 565 | "steps": ["Create a worktree linked to a specific branch."], 566 | "prerequisites": [ 567 | "The target path must not already be a git repository." 568 | ], 569 | "tags": ["worktree", "add"], 570 | "author": "mike-rambil", 571 | "last_updated": "2024-06-10" 572 | }, 573 | { 574 | "Name": "Remove a Worktree", 575 | "category": "Worktree", 576 | "command": "git worktree remove ", 577 | "examples": [ 578 | { 579 | "code": "git worktree remove ../feature-branch", 580 | "description": "Detach a worktree without deleting the files." 581 | }, 582 | { 583 | "code": "git worktree remove ../hotfix", 584 | "description": "Remove a hotfix worktree." 585 | } 586 | ], 587 | "steps": ["Detach a worktree without deleting the files."], 588 | "warnings": [ 589 | "Make sure you have committed all changes before removing a worktree." 590 | ], 591 | "tags": ["worktree", "remove"], 592 | "author": "mike-rambil", 593 | "last_updated": "2024-06-10" 594 | }, 595 | { 596 | "Name": "Switch Between Worktrees", 597 | "category": "Worktree", 598 | "command": "cd ", 599 | "examples": [ 600 | { 601 | "code": "cd ../feature-branch", 602 | "description": "Switch to the worktree directory." 603 | }, 604 | { 605 | "code": "cd ../hotfix", 606 | "description": "Switch to a hotfix worktree." 607 | } 608 | ], 609 | "steps": ["Simply cd into the worktree directory to switch."], 610 | "tags": ["worktree", "switch"], 611 | "author": "mike-rambil", 612 | "last_updated": "2024-06-10" 613 | }, 614 | { 615 | "Name": "Use Worktrees for Temporary Fixes", 616 | "category": "Worktree", 617 | "command": "git worktree add ../hotfix hotfix-branch", 618 | "examples": [ 619 | { 620 | "code": "git worktree add ../hotfix hotfix-branch", 621 | "description": "Quickly apply a fix on another branch without leaving your main branch." 622 | }, 623 | { 624 | "code": "git worktree add ../bugfix bugfix-branch", 625 | "description": "Create a worktree for a bugfix branch." 626 | } 627 | ], 628 | "steps": [ 629 | "Quickly apply a fix on another branch without leaving your main branch." 630 | ], 631 | "tags": ["worktree", "hotfix"], 632 | "author": "mike-rambil", 633 | "last_updated": "2024-06-10" 634 | }, 635 | { 636 | "Name": "Flags and Their Uses", 637 | "flags": { 638 | "add": "Creates a new worktree for an existing branch.", 639 | "-b": "Creates a new worktree with a new branch.", 640 | "list": "Lists all active worktrees.", 641 | "remove": "Detaches a worktree from the repo without deleting files.", 642 | "prune": "Cleans up stale worktree references after manual deletion.", 643 | "move": "Moves a worktree to a different location." 644 | }, 645 | "tags": ["worktree", "flags"], 646 | "author": "mike-rambil", 647 | "last_updated": "2024-06-10" 648 | } 649 | ] 650 | }, 651 | { 652 | "Name": "Sharing Changes as Patch Files", 653 | "category": "Patch & Diff", 654 | "short_description": "Generate and share patch files for committed or uncommitted changes.", 655 | "long_description": "How to create patch files from your changes for sharing via email, SCP, Slack, or other means. Covers both committed (with full commit metadata) and uncommitted changes.", 656 | "tags": ["patch", "diff", "sharing", "email", "collaboration"], 657 | "author": "mike-rambil", 658 | "last_updated": "2024-06-10", 659 | "subtoc": [ 660 | { 661 | "Name": "Create Patch from Last Commit(s)", 662 | "category": "Patch & Diff", 663 | "command": "git format-patch HEAD~1", 664 | "examples": [ 665 | { 666 | "code": "git format-patch HEAD~1", 667 | "description": "Create a .patch file for the last commit." 668 | }, 669 | { 670 | "code": "git format-patch origin/main..HEAD --stdout > my-changes.patch", 671 | "description": "Create a single patch file for all commits on top of main." 672 | }, 673 | { 674 | "code": "git format-patch -2", 675 | "description": "Create patch files for the last two commits." 676 | }, 677 | { 678 | "code": "git format-patch -2 origin/main..HEAD", 679 | "description": "Create patch files for all commits since main." 680 | } 681 | ], 682 | "steps": [ 683 | "Run 'git format-patch HEAD~1' to create a patch for the last commit.", 684 | "Use 'git format-patch origin/main..HEAD --stdout > my-changes.patch' to create a single patch file for multiple commits." 685 | ], 686 | "warnings": [ 687 | "Patch files created this way include commit messages, authorship, and timestamps.", 688 | "Use 'git am' to apply these patches on another system." 689 | ], 690 | "tags": ["patch", "format-patch", "committed"], 691 | "links": [ 692 | { 693 | "label": "Official Docs", 694 | "url": "https://git-scm.com/docs/git-format-patch" 695 | } 696 | ], 697 | "author": "mike-rambil", 698 | "last_updated": "2024-06-10" 699 | }, 700 | { 701 | "Name": "Apply Patch with Commit Metadata", 702 | "category": "Patch & Diff", 703 | "command": "git am my-changes.patch", 704 | "examples": [ 705 | { 706 | "code": "git am my-changes.patch", 707 | "description": "Apply a patch file and preserve commit info." 708 | }, 709 | { 710 | "code": "git am --signoff my-changes.patch", 711 | "description": "Apply a patch and add a Signed-off-by line." 712 | } 713 | ], 714 | "steps": [ 715 | "Run 'git am my-changes.patch' to apply the patch and preserve commit messages, authorship, and timestamps." 716 | ], 717 | "tags": ["patch", "am", "apply"], 718 | "author": "mike-rambil", 719 | "last_updated": "2024-06-10" 720 | }, 721 | { 722 | "Name": "Create Patch from Uncommitted Changes", 723 | "category": "Patch & Diff", 724 | "command": "git diff > changes.diff", 725 | "examples": [ 726 | { 727 | "code": "git diff > changes.diff", 728 | "description": "Create a diff file of uncommitted changes." 729 | }, 730 | { 731 | "code": "git diff HEAD~1 > last-commit.diff", 732 | "description": "Create a diff file for the last commit." 733 | } 734 | ], 735 | "steps": [ 736 | "Run 'git diff > changes.diff' to save uncommitted changes to a file." 737 | ], 738 | "warnings": [ 739 | "This does NOT preserve commit metadata or history—just raw changes." 740 | ], 741 | "tags": ["diff", "uncommitted", "snapshot"], 742 | "links": [ 743 | { 744 | "label": "Official Docs", 745 | "url": "https://git-scm.com/docs/git-diff" 746 | } 747 | ], 748 | "author": "mike-rambil", 749 | "last_updated": "2024-06-10" 750 | }, 751 | { 752 | "Name": "Apply Diff File", 753 | "category": "Patch & Diff", 754 | "command": "git apply changes.diff", 755 | "examples": [ 756 | { 757 | "code": "git apply changes.diff", 758 | "description": "Apply a diff file of uncommitted changes." 759 | }, 760 | { 761 | "code": "git apply --stat changes.diff", 762 | "description": "Show what would change if the diff were applied." 763 | } 764 | ], 765 | "steps": [ 766 | "Run 'git apply changes.diff' to apply the changes from a diff file." 767 | ], 768 | "tags": ["diff", "apply", "uncommitted"], 769 | "author": "mike-rambil", 770 | "last_updated": "2024-06-10" 771 | }, 772 | { 773 | "Name": "Patch vs Diff: Quick Reference", 774 | "category": "Patch & Diff", 775 | "long_description": "| Command | Use Case | Preserves Commit Info? | Can Apply With |\n|---|---|---|---|\n| git diff > file.diff | Share uncommitted changes | ❌ | git apply |\n| git format-patch > file.patch | Share committed changes | ✅ | git am |", 776 | "tags": ["patch", "diff", "reference"], 777 | "author": "mike-rambil", 778 | "last_updated": "2024-06-10" 779 | } 780 | ] 781 | }, 782 | { 783 | "Name": "Pull Changes of Specific Files from a Commit", 784 | "category": "Selective File Restore", 785 | "short_description": "Restore or pull changes for specific files from a past commit without reverting the entire commit.", 786 | "long_description": "How to use git to pull or restore changes for only certain files from a specific commit, without affecting the rest of your working directory or reverting the whole commit. Useful for cherry-picking file-level changes.", 787 | "command": "git checkout -- ", 788 | "examples": [ 789 | { 790 | "code": "git checkout e8ab7f64fdfcc7bdaaed8d96c0ac26dce035663f -- path/to/file1.txt path/to/file2.txt", 791 | "description": "Restore file1.txt and file2.txt from the specified commit." 792 | }, 793 | { 794 | "code": "git add path/to/file1.txt path/to/file2.txt\ngit commit -m \"Pulled changes for file1.txt and file2.txt from commit e8ab7f64\"\ngit push origin revert/productionOrder", 795 | "description": "Stage, commit, and push the restored files to a new branch." 796 | }, 797 | { 798 | "code": "git restore --source e8ab7f64fdfcc7bdaaed8d96c0ac26dce035663f path/to/file1.txt path/to/file2.txt", 799 | "description": "Restore files using the newer 'git restore' command." 800 | } 801 | ], 802 | "steps": [ 803 | "Checkout the specific files from the desired commit using 'git checkout -- '.", 804 | "Stage the changes with 'git add '.", 805 | "Commit the changes with a descriptive message.", 806 | "Push your branch and create a pull request if needed." 807 | ], 808 | "warnings": [ 809 | "This will overwrite the current working directory versions of the specified files.", 810 | "Make sure to commit or stash any local changes to those files before running the command." 811 | ], 812 | "tags": ["checkout", "restore", "file", "commit", "cherry-pick"], 813 | "author": "mike-rambil", 814 | "last_updated": "2024-06-10", 815 | "links": [ 816 | { 817 | "label": "Git Docs: git checkout", 818 | "url": "https://git-scm.com/docs/git-checkout" 819 | } 820 | ] 821 | } 822 | ] 823 | --------------------------------------------------------------------------------