Skip to content
JackSparrow414
Go back

Git Basics and Contributing Pull Requests to Open-Source Projects: Practical Troubleshooting

Table of contents

Open Table of contents

Git Basics and Contributing Pull Requests to Open-Source Projects

Goals

  1. Quickly keep a fork synchronized with its source repository.
  2. Conveniently push changes to the fork and submit a PR to the original repository.
  3. Switch quickly between Gitee and GitHub.
  4. Learn the standard open-source contribution workflow.

Basic Git Operations

Cloning, Creating a Branch, and Committing

  1. Fork a project on GitHub.
  2. Clone it locally.
git clone git@github.com:jacksparrow414/hello-world.git
  1. Create a branch named develop. checkout -b both creates and switches to it.
git checkout -b develop
  1. Modify code on develop.
  2. Stage the changes.
git add .
  1. Commit to the local repository. -a means all and commits the tracked changes; -m supplies a short commit message.
git commit -a -m 'add message'

How Do I Remove a File from the Staging Area?

Use the following command:

git reset HEAD FILE_NAME

Or:

git rm --cached FILE_NAME

What If a Commit Misses a File, Has the Wrong Message, or Fails Code Review?

# Change the previous commit message
git commit --amend -m 'modify message'

To change a committed author, use:

git rebase -i COMMIT_BEFORE_TARGET
# In the interactive editor, choose edit for the target commit; save with :wq
git commit --amend --author="username jack@email.com"
git rebase --continue
# Force-update the remote branch after editing
git push --force origin

For multiple commits, repeat the three steps, or use git-filter-repo for batch changes.

By default, git rebase does not edit the root (first) commit. To include it:

git rebase -i --root
# Add a forgotten file, such as test.txt, after git add test.txt
git commit --amend test.txt
# Vim opens. Edit the message if needed, then save and quit with :wq
# To retain the previous message, use:
git commit --amend --no-edit test.txt
# git log now shows the amended result as one commit
# If code review failed but the change is not abandoned, modify the file and use either form above, then:
git push

Several Ways to Push to GitHub

Pulling Remote Branches

Applying One Commit from develop to master

Switch to master.

git checkout master

View recent Git operation history:

git reflog

Find a commit on develop.

# commitId is the develop commit found in git reflog
git cherry-pick commitID
To cherry-pick several commits, specify a range:
# Range (A,B]: excludes A, includes B
git cherry-pick commitIdA..commitIdB

This applies commits between commitIdA and commitIdB to the current branch.

# Range [A,B]: includes both A and B
git cherry-pick commitIdA^..commitIdB

In IDEA, open Git, select commits on the desired branch, and right-click Cherry-Pick. For example, apply one or more dev commits to the current master branch. Applying Cherry-Pick to a selected commit in the IDEA Git log

Moving HEAD Back Several Steps

Reverting a Problematic Commit Already Pushed Remotely

git revert creates a new commit recording the reversal of an earlier commit.

 # commitId identifies the commit to reverse
 git revert commitId

 git push

If a Local user.name Change Has Not Taken Effect, Use:

git commit --amend --reset-author

Other Git Settings and Common Problems

warning Delete `CR` prettier/prettier

This usually occurs in frontend projects with ESLint. On Windows, cloning may automatically convert LF (line feed) line endings to CRLF (carriage return plus line feed), leaving local files with CRLF.

Disable automatic conversion:

git config --global core.autocrlf false

Fix the files:

yarn run lint --fix

The project can then build and start normally.

Restoring a Branch Deleted Both Locally and Remotely

Use reflog, which records reference changes. Think of it loosely as a database undo log. The default retention is 90 days.

How can we locate the deleted branch?

git reflog --date=iso-local | grep "dev-11788\|11788" | sort

Find reflog entries whose branch or commit message contains dev-11788 or 11788, display timestamps, and sort the grep results. Terminal filtering Git reflog entries by a branch keyword and sorting the results See git log for —date formats.

Find the commit hash at the point to restore.

git checkout commit-hash -b 11788-restore

Common GitHub Operations

Questions

What If Cloning from GitHub Is Slow or Frequently Fails?

After forking a large project, slow GitHub access—such as from mainland China—may prevent a successful clone.

You can synchronize it to Gitee, then run:

git clone GITEE_REPOSITORY_URL

After cloning, add your GitHub fork as another remote.

Format: git remote add CUSTOM_NAME REMOTE_REPOSITORY_URL

Find the URL by selecting Clone and HTTPS in your GitHub repository and copying it.

git remote add person_repo https://github.com/xxxx

origin now points to Gitee. If you only used Gitee for a faster download but want origin to point to your GitHub fork, use:

git remote set-url origin https://github.com/xxxx

This sets origin to your fork on GitHub rather than Gitee.

Afterward, remove the duplicate remote person_repo added earlier.

git remote remove person_repo

Inspect the upstream branches associated with local branches:

git branch -vv

How Do I Keep Synchronized with the Official Repository?

  1. First approach: use the GitHub fork page, as shown.

    • Click Pull request on your fork. Pull request entry on a GitHub fork repository page

    • To submit your changes to the original repository: GitHub comparison page configured to submit a PR from a personal fork to the upstream repository

    • To synchronize the original repository into your fork: GitHub comparison page configured to sync upstream commits into a personal fork submit a PR to the fork and merge it to synchronize. 2021 update: GitHub now provides a Fetch upstream button on forks for convenient synchronization.

  2. Second approach: use the command line.

    • Add another remote pointing to the official repository.

      git remote add upstream UPSTREAM_REPOSITORY_URL
    • I recommend creating a fresh branch for each issue or feature. Create and switch to issue#4673 locally, based on the official master branch:

      git checkout -b issue#4673 upstream/master
      # As discussed for git push, setting upstream simplifies other commands
      git branch --set-upstream-to=upstream/master

      After making changes, pull before committing to check for conflicts.

      git pull

      It pulls from upstream by default because of the setting above. Tip: git pull from the official repository may open Vim with a default “merge branch master of…” message. A subsequent PR then includes that untidy merge history. Solution:

      git pull --rebase=true
      # Or:
      git pull --rebase

      Alternatively, accept the Vim message without edits and save with :wq. This creates parallel history lines; then run:

      git rebase

      The history becomes linear.

      Commit local changes and push to your fork; origin is the fork’s remote alias.

      git push -f origin issue#4673

      Find the pushed branch on your fork’s GitHub page and submit a PR upstream, following the submission steps shown earlier. Why use -f here? It forces the remote branch to match local code. When creating the issue branch and before committing, we synchronized it with official master, so the push makes the remote issue branch match that local state. Also note: after pulling official master, local master is ahead of origin/master. In the situation described here, git push without -f reports ! [rejected] master -> master (non-fast-forward). For normal company teamwork, however, I recommend avoiding -f where possible.

      After upstream merges the PR, switch to master associated with origin and synchronize with the original repository.

      # Without specifying a remote, origin is the default; git checkout upstream/master checks out upstream’s remote-tracking master
      git checkout master
      
      # Pull upstream/master and merge into the current branch
      git pull upstream master

      Local code now matches the original repository.

      Delete the local issue#4673 bug-fix branch.

      git branch -d issue#4673

      Delete the corresponding remote branch.

      git push origin --delete issue#4673

GitHub Usage Guide

The official documentation explains account registration, repository creation, PR submission and merging, Git identity setup, advanced searches by language, stars over 100, author, or recent pushes, and GitHub emoji. You can switch documentation languages as shown below; the first module generally contains the usage reference.

Language selector and documentation categories on the GitHub Docs home pageQuery qualifier examples in the GitHub Docs repository search documentation The GitHub search guide in the Chinese version of GitHub Docs

Closing Thoughts

The complete workflow is now covered.

Notes

Other Operations

  1. Inspect local Git configuration.
    git config --global --list
  2. Configure Git.
    git config --global user.name "YOUR_USERNAME"
    git config --global user.email "YOUR_EMAIL"
  3. Generate an SSH key.
    ssh-keygen -t rsa -C "YOUR_EMAIL"
  4. Clean up stale local remote references.
    git remote prune origin

Tip


Share this post:

Previous Post
Getting Started with SkyWalking
Next Post
ShardingSphere (Part 4): Custom Encryption Strategies for Data Masking

Comments

Questions, corrections, and experiences are welcome. Sign in with GitHub to comment; both language versions share this discussion.

Comments are available on the live site only.