> For AI agents: the complete documentation index is available at https://nhanbe.id.vn/llms.txt, the full documentation bundle is available at https://nhanbe.id.vn/llms-full.txt.

# Git Cheatsheet — Azure DevOps

Personal quick reference for AMS workflow: Azure Repos, multi-project AEM setups, rebase, cherry-pick, hotfix, and `az repos` CLI.

***

## 1. Initial Setup for Azure DevOps

### 1.1 Identity

```bash
git config --global user.name  "John Doe"
git config --global user.email "j.doe@company.com"
git config --global init.defaultBranch main
git config --global pull.rebase true
git config --global rebase.autoStash true
git config --global core.autocrlf true   # Windows
git config --global core.longpaths true  # Windows + AEM (path > 260 chars)
```

### 1.2 Authentication

**GCM (Recommended)** — Bundled with Git for Windows, handles MFA automatically:

```bash
git config --global credential.helper manager
```

**PAT (Personal Access Token)** — Generate at User Settings → Personal Access Tokens (scope `Code Read & Write`):

```bash
git clone https://YOUR_PAT@dev.azure.com/{org}/{project}/_git/{repo}
```

**SSH:**

```bash
ssh-keygen -t ed25519 -C "email@company.com"
# Upload ~/.ssh/id_ed25519.pub → Azure DevOps → SSH Public Keys
git clone git@ssh.dev.azure.com:v3/{org}/{project}/{repo}
```

***

## 2. Clone & Remote

```bash
git clone https://dev.azure.com/{org}/{project}/_git/{repo}
git clone --depth=1 <url>                                        # Shallow clone
git clone -b release/v1.2 --single-branch <url>

git remote add upstream https://dev.azure.com/.../_git/{repo}
git remote set-url origin git@ssh.dev.azure.com:v3/{org}/{project}/{repo}
git remote -v
git fetch --all --prune
```

***

## 3. Branching

**Naming Convention:**

```text
main / develop / release/v1.2
feature/{work-item-id}-desc
bugfix/{work-item-id}-desc
hotfix/{work-item-id}-desc
users/{alias}/scratch
```

```bash
git switch -c feature/12345-add-login
git switch main

git branch -a                        # List local + remote branches
git branch -vv                       # Display tracking info
git branch --merged main
git branch --no-merged main

git branch -m old-name new-name
git branch -d feature/done           # Safe delete
git branch -D feature/abandoned      # Force delete
git push origin --delete feature/x   # Delete remote branch
```

> Work Item linking: Include `#12345` in commit messages or PR descriptions for automatic Azure linking.

***

## 4. Commits

```bash
git status -sb
git add file1 file2
git add -p                           # Interactive hunk staging
git add -u                           # Tracked files only

git commit -m "feat(login): add Azure AD SSO #12345"
git commit -am "Subject"
git commit --amend
git commit --amend --no-edit
```

Conventional Commits pattern: `feat|fix|refactor|chore|docs(scope): message #work-item`

### 4.1 Diff & Log

```bash
git diff                             # Working tree vs index
git diff --staged                    # Index vs HEAD
git diff main...feature/x
git diff --stat / --name-only

git log --oneline --graph --all --decorate -20
git log --author="John" --since="1 week ago"
git log -p path/to/file
git log -S"functionName"             # Search commits modifying symbol
git log --follow path/file           # Trace across file renames
```

### 4.2 Blame

```bash
git blame -L 50,100 file.java
git blame -w -M -C file.java         # Ignore whitespace, detect moves/copies
```

***

## 5. Syncing with Remote

```bash
git fetch origin
git fetch --prune
git fetch --all --tags

git pull --rebase origin main
git pull --ff-only

git push -u origin feature/12345
git push --force-with-lease         # Do NOT force push to main/develop/release/*
git push --tags
```

***

## 6. Rebase

### 6.1 Syncing Feature Branch with Main

```bash
git switch feature/12345
git fetch origin
git rebase origin/main
# Conflict → resolve → git add → git rebase --continue
# Abort    → git rebase --abort
git push --force-with-lease
```

### 6.2 Interactive Rebase — Cleaning Commits Before PR

```bash
git rebase -i origin/main
```

| Action   | Description                                            |
| -------- | ------------------------------------------------------ |
| `pick`   | Retain commit as-is                                    |
| `reword` | Modify commit message                                  |
| `squash` | Combine into previous commit and merge commit messages |
| `fixup`  | Combine into previous commit and discard message       |
| `drop`   | Remove commit                                          |
| `edit`   | Pause rebase to amend commit                           |

### 6.3 Autosquash

```bash
git commit --fixup=<sha>
git rebase -i --autosquash origin/main
```

***

## 7. Merge Strategies

```bash
git merge --no-ff feature/12345     # Preserve merge commit
git merge --ff-only feature/12345   # Fast-forward only
git merge --squash feature/12345    # Squash into single commit
git merge --abort
```

| Strategy        | When to Use                                                         |
| --------------- | ------------------------------------------------------------------- |
| **Squash**      | Feature branch contains many small commits; keep main history clean |
| **Rebase + FF** | Linear history preferred; retain individual commits                 |
| **Merge no-FF** | Explicitly record merge points in history                           |

> Configure merge policies in Azure: **Repos → Branches → main → Branch policies → Limit merge types**.

***

## 8. Cherry-Pick — Porting Fixes to Release Branches

```bash
git switch release/v1.2
git cherry-pick <sha>
git cherry-pick <sha1> <sha2> <sha3>
git cherry-pick A..B                 # Commit range (exclusive..inclusive)
git cherry-pick -n <sha>             # Stage changes without committing

# Conflict → git add → git cherry-pick --continue
# Abort    → git cherry-pick --abort
```

***

## 9. Stashing

```bash
git stash push -m "WIP login form"
git stash push -u                    # Include untracked files
git stash list
git stash show -p stash@{0}
git stash pop                        # Apply and drop stash entry
git stash apply stash@{0}            # Apply and retain stash entry
git stash drop stash@{0}
git stash clear
git stash branch new-branch          # Create new branch from stash
```

***

## 10. Undo & Recovery

| Scenario                                       | Command                                           |
| ---------------------------------------------- | ------------------------------------------------- |
| Discard unstaged changes                       | `git restore &lt;file&gt;`                        |
| Unstage changes                                | `git restore --staged &lt;file&gt;`               |
| Untrack file                                   | `git rm --cached &lt;file&gt;`                    |
| Reset commit (keep working dir & index)        | `git reset --soft HEAD~1`                         |
| Reset commit (keep working dir, unstage index) | `git reset --mixed HEAD~1`                        |
| Hard reset (discard all uncommitted changes)   | `git reset --hard HEAD~1`                         |
| Create inverse commit                          | `git revert &lt;sha&gt;`                          |
| Revert merge commit                            | `git revert -m 1 &lt;merge-sha&gt;`               |
| Locate lost commits                            | `git reflog`                                      |
| Restore deleted branch                         | `git switch -c feature/x &lt;sha-from-reflog&gt;` |
| Restore deleted file                           | `git checkout HEAD~1 -- path/file`                |

***

## 11. Tagging & Releases

```bash
git tag -a v1.2.0 -m "Release 1.2.0"   # Annotated tag (recommended)
git tag v1.2.0-rc1                       # Lightweight tag
git tag -a v1.2.0 <sha> -m "..."        # Tag historic commit

git push origin v1.2.0
git push --tags

git tag -d v1.2.0
git push origin --delete v1.2.0

git tag --sort=-creatordate | head
```

***

## 12. Submodules

```bash
git submodule add https://dev.azure.com/.../_git/project-a project-a
git submodule update --init --recursive
git submodule update --remote --merge
git clone --recurse-submodules <url>
```

> For AEM monorepos, a **monorepo with path-based pipeline triggers** is easier to maintain than git submodules.

***

## 13. Sparse Checkout — Checkout Specific Sub-Projects

```bash
git clone --filter=blob:none --no-checkout <url>
cd repo
git sparse-checkout init --cone
git sparse-checkout set project-a shared-libs
git checkout main

git sparse-checkout add project-b
git sparse-checkout disable
```

***

## 14. Pull Requests via Azure CLI

```bash
az extension add --name azure-devops
az devops login
az devops configure --defaults organization=https://dev.azure.com/{org} project={project}
```

```bash
az repos pr create \
  --repository my-repo \
  --source-branch feature/12345-add-login \
  --target-branch main \
  --title "feat(login): Add Azure AD SSO #12345" \
  --work-items 12345 \
  --reviewers a@company.com b@company.com \
  --delete-source-branch true \
  --auto-complete true \
  --squash true

az repos pr list --status active
az repos pr show --id 123
az repos pr set-vote --id 123 --vote approve
az repos pr update --id 123 --status completed
az repos pr work-item add --id 123 --work-items 12345
```

***

## 15. Pipeline Triggers

```yaml
trigger:
  branches:
    include: [main, release/*]
  paths:
    include: [project-a/**]
    exclude: ['**/*.md', docs/**]

pr:
  branches:
    include: [main]
  paths:
    include: [project-a/**]
```

Skip CI execution: Add `[skip ci]` or `***NO_CI***` to commit message.

***

## 16. Branch Policy Checklist

**Repos → Branches → main → Branch policies:**

- Minimum 2 required reviewers, reset votes on new pushes
- Require linked Work Items
- Build validation before merging
- Status checks: CodeQL / SonarCloud / Snyk
- Require resolved comment threads
- Limit merge types: Require Squash or Rebase only

***

## 17. Conflict Resolution

```bash
# Rebase conflict resolution
git mergetool                        # Or manually edit conflict markers <<<<< ===== >>>>>
git add path/file
git rebase --continue
git rebase --abort                   # Abort rebase

# Accept changes from one side
git checkout --ours   path/file      # Keep current branch version
git checkout --theirs path/file      # Accept incoming branch version
git add path/file
```

**AEM `.content.xml` Conflicts** — Ignore attribute reordering conflicts:

```bash
echo "ui.content/**/.content.xml merge=ours" >> .gitattributes
git config merge.ours.driver true
```

***

## 18. Multi-Project Branching Models

**Option 1 — Monorepo (Recommended):**

```text
repo/
├── project-a/ | project-b/ | project-c/
└── azure-pipelines/
    ├── project-a.yml
    └── project-b.yml
```

Branch prefix format: `feature/project-a/12345-desc`, `hotfix/project-b/67890-fix`

**Option 2 — Multi-Repo + Umbrella Repository:**
Each project lives in a distinct Azure Repo; meta repo uses submodules pinned to specific commits.

***

## 19. Useful Git Aliases (`~/.gitconfig`)

```ini
[alias]
    st  = status -sb
    co  = checkout
    sw  = switch
    br  = branch
    cm  = commit -m
    ca  = commit --amend
    can = commit --amend --no-edit
    lg  = log --oneline --graph --all --decorate -30
    last = log -1 HEAD --stat
    unstage = restore --staged
    discard = restore
    pf  = push --force-with-lease
    cleanup = "!git branch --merged main | grep -v '^\\*\\|main\\|develop' | xargs -r git branch -d"
    pr-list = "!az repos pr list --status active --output table"
    sync = "!git fetch --all --prune && git rebase origin/$(git branch --show-current)"
    wip = "!git add -A && git commit -m 'WIP'"
    unwip = "reset HEAD~1 --mixed"
```

***

## 20. Troubleshooting

| Issue                             | Solution                                                                                      |
| --------------------------------- | --------------------------------------------------------------------------------------------- |
| `fatal: Authentication failed`    | PAT expired → regenerate token; GCM cached stale credentials → `git credential-manager erase` |
| Conditional Access block          | PAT requires `vso.code_write` scope                                                           |
| `LF will be replaced by CRLF`     | Set `git config --global core.autocrlf true` (Windows)                                        |
| `filename too long` (AEM/Windows) | Set `git config --system core.longpaths true`                                                 |
| Push rejected (Branch Policy)     | Direct push prohibited on `main` → submit Pull Request                                        |
| Repository size too large         | Shallow clone `git clone --depth=20` or `--filter=blob:none`                                  |

Standard `.gitattributes` for AEM projects:

```text
* text=auto eol=lf
*.bat text eol=crlf
*.cmd text eol=crlf
*.sh  text eol=lf
```

**Accidentally Committed Secret:**

```bash
# Unpushed commit
git reset --soft HEAD~1   # Remove secret and recommit

# Already pushed — rewrite history and notify team
git filter-repo --invert-paths --path path/to/secret.txt
git push --force-with-lease
# Revoke compromised PAT/secret immediately in Azure DevOps Portal
```

***

## 21. Daily Workflow Summary

```bash
# Start of workday
git fetch --all --prune
git switch main && git pull --rebase

# Create new feature branch
git switch -c feature/12345-desc
# ... work on code ...
git add -p
git commit -m "feat(scope): message #12345"

# Before PR — clean up history
git fetch origin
git rebase -i origin/main
git push -u origin feature/12345-desc
# Or use force-with-lease if previously pushed
git push --force-with-lease

# Create PR
az repos pr create --source-branch feature/12345-desc --target-branch main \
  --title "..." --work-items 12345 --auto-complete true --squash true

# After PR merge
git switch main && git pull --rebase
git branch -d feature/12345-desc
```

***

## 22. References

- [Azure Repos Git Documentation](https://learn.microsoft.com/en-us/azure/devops/repos/git/)
- [az repos CLI Reference](https://learn.microsoft.com/en-us/cli/azure/repos)
- [Azure DevOps Branch Policies](https://learn.microsoft.com/en-us/azure/devops/repos/git/branch-policies)
- [Git Credential Manager](https://github.com/git-ecosystem/git-credential-manager)
- [Conventional Commits Specification](https://www.conventionalcommits.org/)
