High-Frequency Git Operations for Everyday Development
Here are some of the most frequent Git operations you may need in day-to-day development.
Connect Your Local Folder to a GitHub Repository
Scenario
You have an existing local folder with files and want to connect it to an already existing GitHub repository.
Steps
Initialize Git in your folder:
1 | |
Add your GitHub repository (replace URL with your repo):
1 | |
Fetch remote history:
1 | |
Merge remote and local files, allowing unrelated histories (change main to your repo's default branch if necessary):
1 | |
If you see an error like:
The following untracked working tree files would be overwritten by merge...
We recommend:
1 | |
Commit after resolving all conflicts:
1 | |
Push to the remote repository (if needed):
1 | |
The --set-upstream origin main option is only needed for the first push; you don't need it afterward.
List What Files git add . Would Stage
1 | |
Example Output:
1 | |
Breakdown:
M= Modified (but not staged)??= Untracked (new files)
Remove Previously Committed Files Now in .gitignore
Scenario
You added rules to .gitignore but some files were already committed.
Steps
Stage removal of all currently tracked files (but not delete locally):
1 | |
Add everything back to the repo ("add" skips gitignored files):
1 | |
Commit the change:
1 | |
At this point, the files are only removed from the repository from this commit onward (they'll still exist in older commits/history). If you want them removed from previous commits as well, consider squashing multiple commits into a single commit, as explained below.
List Files Added, Removed, or Changed Relative to Another Commit
Run git status and ensure you have no unstaged changes or staged but uncommitted changes. Then, to compare the current state (HEAD) against commit abcdef1:
1 | |
Output looks like:
1 | |
- Added (A): File is present in
HEADbut not inabcdef1. - Deleted (D): File is present in
abcdef1, but not inHEAD. - Modified (M): File exists in both, but contents changed.
Squash Multiple Commits into a Single Commit
Scenario
You have made several small commits (some of which may be faulty or embarassing) and want to clean up history by squashing them into one.
Steps
Review commit history:
1 | |
Decide how many previous commits you want to squash.
Start an interactive rebase, e.g. with the last 3 commits:
1 | |
In the opened editor:
- Leave
pickfor the first commit. - For the others, change
picktosquash(or justs). - Save and close.
You will then enter a second editor session. Edit the combined commit message. Save and close.
Force-push the branch to rewrite history on GitHub:
1 | |
Note
- Use squashing carefully if collaborating, as force push overwrites history.
List Branches
List local branches:
1 | |
List remote branches:
1 | |
List local and remote branches:
1 | |
List Commits in Branches
To list commits in the branch feature:
1 | |
Get Files and Folders from Another Branch or Commit
Copy files and folders from the tip of branch feature into your current working directory:
1 | |
Copy files and folders from commit abcdef1 into your current working directory:
1 | |
Print a file from the tip of branch feature to STDOUT:
1 | |
Print a file from commit abcdef1 to STDOUT:
1 | |
Push a New Branch in Your Local Repo to the upstream Remote (not your own origin)
Checkout the new branch:
1 | |
Add and commit files as usual, for example:
1 | |
Use the following command to push:
1 | |
Delete a Local Branch
1 | |
This will refuse if the branch contains undeleted/unmerged changes.
Overwriting Branch History to Match Upstream
Fetch the latest changes:
1 | |
Make backups of your files outside of the repository. See "Get Files and Folders from Another Branch or Commit" for how.
Reset your branch to upstream. WARNING: This will override your branch. Local changes/commits not in upstream will be lost.
1 | |
Push the changes to your fork. This will overwrite your fork's main branch on GitHub/etc to match upstream, removing commit B:
1 | |
Create a New Commit Merging with Another Commit on Another Branch
Assumptions:
- You are on the latest commit
Con branchB. - You want to merge in the content from commit
C'on branchB'and create a new commitCConB.
Fetch the latest info:
1 | |
Ensure you're on branch B:
1 | |
Manually assess the differences between C and C' by listing files added, removed, or changed relative to C'.
Scenario 1: CC should be a complete clone of C
Here, you want to do a merge, but content stays as in C; only history merges. CC is a merge commit, with parents C and C', tree is identical to C.
1 | |
Scenario 2: CC should be a complete clone of C'
You want a merge commit on branch B (so CC has parents C and C'), but override all files so they match C' (even if that discards local changes).
1 | |
Scenario 3: CC mixes content from C and C'
1 | |
List Remotes
1 | |
This will display a list of remotes with their URLs, e.g.:
1 | |
Push to a Specific Remote
1 | |
<remote-name>is the name of the remote you want to push to (e.g.,origin,upstream, etc).<branch-name>is the branch you want to push (e.g.,main,master, etc).
Keep a Fork Updated with an Original Repository
If you've forked a repository on GitHub, your fork won't automatically stay up to date as the original repository changes. By default, your fork links only to itself (as origin), and not to the original repository. To pull in updates from the source, you'll want to add the original repository as a new remote, commonly named upstream.
Here's a quick guide to achieve this:
1. Find the Original Repository URL
First, go to the original repository (not your fork) on GitHub. Copy the repository's clone URL (use either HTTPS or SSH, depending on your setup).
2. Add the Original Repository as a Remote Called upstream
Open your terminal and navigate to your local copy of the forked repository. Then add the original as a new remote called upstream:
1 | |
(Replace the URL above with the actual URL of the original repository.)
3. Confirm Your Remotes
To make sure everything is set up correctly, run:
1 | |
You should see output similar to:
1 | |
4. Fetch Updates from the Original Repository
You can now fetch all the latest branches and updates from the original repository using:
1 | |