gglink.ir

Learn Git - Version Control

Git Knowledge Summary


Core Concepts

Commands


Setup & Basic Workflow

This section covers initializing a repository, configuring Git, and the fundamental "add, commit, check status" loop.

Command Description
git init Initializes a new Git repository in the current directory.
git clone <url> Clones an existing repository from a remote URL to your local machine.
git config --global user.name "<name>" Sets the user name that will be attached to your commits.
git config --global user.email "<email>" Sets the email address that will be attached to your commits.
git config --global init.defaultBranch <name> Sets the name for the default branch (e.g., main).
git status Displays the state of the working directory and the staging area.
git add <file> Stages changes in the specified file for the next commit.
git add . Stages all changes (new, modified, deleted) in the current directory.
git add -p Interactively stages portions of changes within files.
git commit -m "<msg>" Records staged changes to the repository with a descriptive message.
git commit -am "<msg>" Stages all tracked, modified files and commits them in one step.
git commit --amend Amends the most recent commit (e.g., to change the message or add files).
git log Shows the commit history for the current branch.
git log --oneline --graph --decorate A more concise, visual log showing branches and commit history.
git diff Shows changes in the working directory that are not yet staged.
git diff --staged Shows changes that are staged but not yet committed.
git diff <branch1>..<branch2> Shows the differences between two branches.
git rm <file> Removes a file from the working directory and stages the removal.
git mv <old-name> <new-name> Renames a file and stages the move.

Branching Commands

This section focuses on all commands related to creating, managing, and integrating branches.

Command Description
git branch Lists all local branches. git branch -a lists all local and remote branches.
git branch <branch-name> Creates a new branch based on the current commit.
git branch -d <branch-name> Deletes a specified local branch (if it has been merged).
git branch -D <branch-name> Force-deletes a specified local branch (even if unmerged).
git branch -m <old-name> <new-name> Renames a branch.
git branch -vv Lists all local branches with their upstream tracking information.
git merge <branch> Merges changes from the specified branch into the current branch.
git merge --no-ff <branch> Merges, but creates a merge commit even if a fast-forward is possible.
git merge --abort Aborts a merge operation that has conflicts.
git rebase <branch> Applies commits from the current branch onto the tip of <branch>.
git rebase -i <commit> Interactively rebase commits, allowing for reordering, squashing, editing, etc.
git rebase --continue Continues a rebase after resolving conflicts.
git rebase --abort Aborts a rebase operation and returns to the state before it began.
git cherry <branch> Shows the commits in <branch> that are not in the current branch.
git cherry-pick <commit> Applies the changes from a specific commit to the current branch.

|


Checkout & Navigation (The checkout, switch, and restore commands)

This section covers commands used to move around the repository, switch branches, and discard changes. Note: git switch and git restore are modern commands (added in Git 2.23) that are recommended over the "overloaded" git checkout for these actions.

Command Description
Modern Commands (Recommended)
git switch <branch> Switches the HEAD pointer and working directory to the specified branch.
git switch -c <new-branch> Creates a new branch and switches to it.
git restore <file> Discards changes in the specified file in the working directory.
git restore --staged <file> Unstages a file, moving it from the staging area back to the working directory.
Legacy checkout Command
git checkout <branch> (Legacy) Switches to the specified branch. (Use git switch instead).
git checkout -b <new-branch> (Legacy) Creates a new branch and switches to it. (Use git switch -c instead).
git checkout -- <file> (Legacy) Discards changes in the specified file. (Use git restore instead).
git checkout <commit> -- <file> Checks out a specific version of a file from a past commit.
git checkout <commit> Enters a "detached HEAD" state, checking out a specific commit, not a branch.

Working with Remotes

These commands are essential for collaborating with others and synchronizing your local repository with a remote one.

Command Description
git remote -v Displays the remote repositories (and their URLs) associated with your local repo.
git remote add <name> <url> Adds a new remote repository with a specified name (e.g., origin).
git remote remove <name> Removes the remote repository specified by <name>.
git remote set-url <name> <new-url> Changes the URL for a remote repository.
git fetch Retrieves all updates from all remote repositories without merging.
git fetch <remote-name> Retrieves updates from a specific remote (e.g., git fetch origin).
git pull Fetches changes from the remote and merges them into the current branch.
git pull --rebase Fetches changes and rebases your local commits on top of the remote changes.
git push Pushes committed changes from your current local branch to its upstream remote branch.
git push <remote-name> <branch-name> Pushes a specific branch to a specific remote.
git push -u <remote-name> <branch-name> Pushes a branch and sets it to track the remote branch (links them).
git push --force-with-lease A safer way to force-push, as it won't overwrite remote work you haven't seen.
git push <remote-name> --delete <branch> Deletes a specific branch on the remote repository.

Advanced & Utility Commands

This section includes commands for inspecting history, undoing mistakes, and other useful tools.

Command Description
git stash Temporarily saves changes that are not ready to be committed.
git stash list Lists all stashed changes.
git stash pop Applies the most recent stash and then removes it from the stash list.
git stash apply Applies the most recent stash but leaves it in the stash list.
git stash drop Deletes the most recent stash.
git reset <commit> (Mixed reset) Moves HEAD to <commit> and unstages changes made since.
git reset --soft <commit> Moves HEAD to <commit> but leaves changes staged (ready to re-commit).
git reset --hard <commit> (Dangerous) Moves HEAD to <commit> and discards all changes since.
git revert <commit> Reverts a commit by creating a new commit that undoes the changes.
git reflog Shows a log of all actions HEAD has taken. Your "safety net" for recovering lost commits.
git blame <file> Shows who made changes to each line of the specified file and in which commit.
git show <commit> Displays information about a specific commit (metadata and changes).
git tag <tag-name> Creates a lightweight tag at the current commit.
git tag -a <tag-name> -m "<msg>" Creates an annotated tag (recommended) with a message.
git push --tags Pushes all local tags to the remote repository.
git clean -fd (Dangerous) Removes all untracked files (-f for force) and directories (-d).
git bisect Uses binary search to find the specific commit that introduced a bug.
git archive Creates an archive (e.g., a .zip file) of files from a particular tree or commit.

Cherry pick


The standard command is:

git cherry-pick <start-commit-hash>..<end-commit-hash>

Important: This command selects all commits after <start-commit-hash> up to and including <end-commit-hash>. The starting commit itself is not included.

Including the Starting Commit

If you want to include the <start-commit-hash> in the range as well, you must add a ^ (caret) symbol to it:

git cherry-pick <start-commit-hash>^..<end-commit-hash>

This tells Git to start from the parent of the <start-commit-hash>, thus including the <start-commit-hash> itself in the list of commits to be picked.

Useful Option

git cherry-pick -n <start-commit-hash>^..<end-commit-hash>
# (Review changes)
git commit -m "Cherry-picked features from C to E"

Git rebase

git rebase -i (or git rebase --interactive) is a powerful command that lets you clean up your local commit history before sharing it with others.

Think of it as opening a "to-do list" for your recent commits. Instead of just accepting your history as is, you get to edit that list, changing what you did and how it's presented.

The main use case is to make your commit history clean and easy to read before you merge it into a shared branch (like main) or open a pull request.

How It Works: The Basic Steps

  1. You run the command: You tell Git which commits you want to edit. A common way is git rebase -i HEAD~3. This means "I want to interactively rebase the last 3 commits."

  2. Git opens an editor: Git opens your default text editor with a "to-do" list of the commits you selected. It looks something like this:

    pick 1a2b3c4 Add login button
    pick 5d6e7f8 Fix typo in login button
    pick 9a8b7c6 Add user profile page
    
    # Rebase 1a2b3c4..9a8b7c6 onto 1a2b3c4 (3 commands)
    #
    # Commands:
    # p, pick = use commit
    # r, reword = use commit, but edit the commit message
    # s, squash = use commit, but meld into previous commit
    # d, drop = remove commit
    # ...and more
    
  3. You edit the list: You change the "command" (the word pick) for each commit to tell Git what you want to do.

  4. You save and close: When you save and close the editor, Git executes your "to-do" list from top to bottom.

The Most Common Commands

Here are the most common commands you'll use in that interactive list:

Example

Let's say your history looks messy like this:

$ git log --oneline
9a8b7c6 (HEAD -> feature) Add user profile page
5d6e7f8 Fix typo
1a2b3c4 Add login button

This is messy. The "Fix typo" commit isn't useful. We want to combine it with "Add login button" and reword the "Add user profile page" commit.

Step 1: Run the command to edit the last 3 commits.

git rebase -i HEAD~3

Step 2: Your editor opens. You edit the file to look like this:

# Change 'pick' to 'reword' on the first line
r 1a2b3c4 Add login button

# Change 'pick' to 'fixup' to merge it into the commit above
f 5d6e7f8 Fix typo

# Leave this as 'pick' (or change order, etc.)
p 9a8b7c6 Add user profile page

Step 3: Save and close the editor.

Step 4: Git executes your list:

  1. It stops at 1a2b3c4 and opens an editor for you to reword the message. You change it to "feat: Add login button" and save.
  2. It automatically fixup 5d6e7f8 into the newly reworded commit. No questions asked.
  3. It picks 9a8b7c6 as-is.

The Result: Your history is now clean and looks like this:

$ git log --oneline
c4d5e6f (HEAD -> feature) Add user profile page
a1b2c3d feat: Add login button

You now have two clean commits instead of three messy ones.

⚠️ The Golden Rule of Rebasing

NEVER use git rebase -i on commits that you have already pushed and shared with other people (e.g., on the main or develop branch).

Rebasing rewrites history by creating brand new commits. If you rewrite history that others are already working on, it will cause massive conflicts and problems for your team.

Use it only on your own local commits that nobody else has seen.

Modal Image