Wednesday

Some Handy Git Use Cases

Let's dive deeper into Git commands, especially those that are more advanced and relate to your workflow.

Understanding Your Workflow

Your provided commands outline a common workflow:

  1. Feature Branch Development: You're working on a feature branch (STGF2201-7370).
  2. Staying Updated: You're fetching and integrating changes from the team's development branch (develop_backtest_integ_v3).
  3. Reviewing Changes: You're using git log -p, gitk, and git show to examine differences and commit details.
  4. Tagging: You're using git tag to mark specific commits.

Advanced Git Commands and Concepts

Here's a breakdown of related and advanced commands, organized for clarity:

1. Branching and Merging (Beyond Basic Pulls)

  • git rebase:
    • Purpose: Integrates changes from one branch into another by reapplying commits on top of the target branch. This creates a cleaner, linear history.
    • Usage:
      Bash
      git checkout GTNF2201-7370
      git rebase origin/develop_backtest_integ_v3
      
    • Explanation: This rewrites your feature branch's history as if you had branched off the latest develop_backtest_integ_v3.
    • Caution: Rebase rewrites history, so avoid rebasing branches that have already been pushed and shared with others.
  • git merge --squash:
    • Purpose: Combines all changes from a feature branch into a single commit on the target branch.
    • Usage:
      Bash
      git checkout develop_backtest_integ_v3
      git merge --squash GTNF2201-7370
      git commit -m "Merged feature branch GTNF2201-7370"
      
    • Explanation: This is useful for creating a clean history when merging feature branches, especially when those branches contain many small commits.
  • git cherry-pick:
    • Purpose: Applies specific commits from one branch to another.
    • Usage:
      Bash
      git checkout target_branch
      git cherry-pick <commit_hash>
      
    • Explanation: This is useful for selectively incorporating changes from other branches.
  • git branch -D <branch_name>:
    • Purpose: Force deletes a branch.
    • Explanation: Use this when a normal git branch -d fails because the branch hasn't been fully merged.

2. Inspecting Changes (Advanced)

  • git diff:
    • Purpose: Shows differences between commits, branches, or files.
    • Usage:
      • git diff: Shows changes since the last commit.
      • git diff <commit1> <commit2>: Shows changes between two commits.
      • git diff <branch1> <branch2>: Shows changes between two branches.
      • git diff --staged: Shows changes that are staged for commit.
      • git diff --name-status <commit1> <commit2>: shows only the file names that changed, and the type of change (A=added, M=modified, D=deleted).
  • git bisect:
    • Purpose: Helps find the commit that introduced a bug by performing a binary search through the commit history.
    • Usage:
      Bash
      git bisect start
      git bisect bad <bad_commit>
      git bisect good <good_commit>
      
    • Explanation: Git will automatically check out commits, and you'll mark them as "good" or "bad" until the problematic commit is identified.
  • git blame:
    • Purpose: Shows who last modified each line of a file and when.
    • Usage:
      Bash
      git blame <file_name>
      
    • Explanation: This is useful for understanding the history of specific lines of code.

3. Rewriting History (Use with Caution)

  • git commit --amend:
    • Purpose: Modifies the last commit.
    • Usage:
      Bash
      git commit --amend
      
    • Explanation: This allows you to change the commit message or add/remove files from the last commit.
  • git rebase -i (Interactive Rebase):
    • Purpose: Allows you to edit, reorder, squash, or drop commits during a rebase.
    • Usage:
      Bash
      git rebase -i <commit_hash>
      
    • Explanation: This is a powerful tool for cleaning up your commit history.
  • git reset:
    • Purpose: Resets the current branch to a specific commit.
    • Usage:
      • git reset --soft <commit_hash>: Keeps changes staged.
      • git reset --mixed <commit_hash>: Keeps changes unstaged.
      • git reset --hard <commit_hash>: Discards all changes.
    • Caution: git reset --hard can result in data loss, so use it carefully.
  • git reflog:
    • Purpose: Shows a log of all changes to the HEAD pointer, including branch switches, resets, and commits.
    • Explanation: This is a safety net that allows you to recover from mistakes.

4. Stashing

  • git stash:
    • Purpose: Temporarily saves changes that are not ready to be committed.
    • Usage:
      • git stash: Saves changes.
      • git stash list: Lists stashed changes.
      • git stash apply: Applies the last stashed changes.
      • git stash pop: Applies and removes the last stashed changes.
      • git stash drop <stash_id>: Removes a specific stash entry.

Example scenarios:

  • You need to work on a hotfix while in the middle of your feature branch:
    1. git stash
    2. git checkout main
    3. Create hotfix branch, make changes, commit, and merge.
    4. git checkout GTNF2201-7370
    5. git stash pop

Important Considerations

  • Collaboration: When working in a team, communicate before rewriting shared history.
  • Understanding History: Learn how to interpret Git logs and visualize commit graphs.
  • Practice: The best way to learn Git is to use it regularly.

Some More Commands Revisited with Advanced Context

  1. git switch GTNF2201-7370
    • Explanation: You're switching to your feature branch.
    • Advanced:
      • git switch -c new_branch: Creates and switches to a new branch in one command.
      • git switch -: switch back to the last branch.
  2. git fetch origin develop_backtest_integ_v3
    • Explanation: You're fetching the latest changes from the remote develop_backtest_integ_v3 branch.
    • Advanced:
      • git fetch origin: Fetches all branches from the remote.
      • git fetch --prune origin: removes remote-tracking references to remote branches that no longer exist on the remote. This is very useful for cleaning up local clutter.
  3. git log -p HEAD..FETCH_HEAD or gitk HEAD..FETCH_HEAD
    • Explanation: You're inspecting the changes between your local HEAD and the fetched FETCH_HEAD.
    • Advanced:
      • git log --graph --oneline --decorate: Provides a concise graphical representation of the commit history.
      • git log --author="Your Name": Filters logs by author.
      • git log --since="YYYY-MM-DD" --until="YYYY-MM-DD": Filters logs by date range.
      • git log --grep="search term": filters commits by commit message content.
      • git log -S"string": Find commits that change addition or removal of particular strings.
  4. git pull origin develop_backtest_integ_v3
    • Explanation: You're pulling (fetching and merging) the remote changes into your feature branch.
    • Advanced:
      • git pull --rebase origin develop_backtest_integ_v3: Pulls and rebases instead of merging, creating a cleaner history.
      • If merge conflicts arise, use git status to locate the files, manually resolve the conflicts, git add the resolved files, and then git commit.
  5. gitk HEAD...FETCH_HEAD
    • Explanation: You're viewing the symmetric difference between your HEAD and FETCH_HEAD.
    • Advanced: This is very good for seeing what changes are unique to each branch.
  6. git show c82a22c39cbc32576f64f5c6b3f24b99ea8149c7, git show HEAD^, git show HEAD^^, git show HEAD~4
    • Explanation: You're viewing the details of specific commits.
    • Advanced:
      • git show --stat: Shows the statistics of the changes in a commit.
      • git show --name-only: Shows only the names of the files changed in a commit.
  7. git tag v3 1b2e1d63ff
    • Explanation: You're creating a tag named v3 for the commit 1b2e1d63ff.
    • Advanced:
      • git tag -a v3 -m "Release v3": Creates an annotated tag with a message. Annotated tags are recommended.
      • git tag -d v3: Deletes the tag v3.
      • git push origin v3: Pushes the tag to the remote repository.
      • git tag -l "v*": Lists all tags matching the pattern "v*".
  8. git log v3..v2, git log v2.., git log --since="2 weeks ago", git log v2.. Makefile
    • Explanation: You're filtering the commit log based on tags, dates, and file paths.
    • Advanced: Combine these filters for complex queries. For example, git log --author="Your Name" --since="1 week ago" Makefile.

Workflow Enhancements

  • Pre-commit Hooks:
    • Create scripts that run automatically before each commit to enforce code style, run tests, or prevent committing certain files.
    • This can be done by placing executable scripts inside the .git/hooks/ directory.
  • Git Aliases:
    • Create shortcuts for frequently used Git commands.
    • Example: git config --global alias.co checkout allows you to use git co instead of git checkout.
  • Using a GUI Client:
    • Tools like GitKraken, SourceTree, or GitHub Desktop can provide a visual interface for Git, making complex operations easier.
  • Commit Message Conventions:
    • Establish clear and consistent commit message conventions within your team.
    • This makes it easier to understand the history and track changes.
  • Code Reviews:
    • Use pull requests or merge requests to facilitate code reviews before merging changes into the main branch.
    • This helps to catch bugs and improve code quality.

By mastering these commands, you'll be able to manage your Git repositories more effectively and collaborate more efficiently.

No comments:

Some Handy Git Use Cases

Let's dive deeper into Git commands, especially those that are more advanced and relate to your workflow. Understanding Your Workflow Yo...