Contributing via forking on Git hosts like GitHub
github working with local desktop
(a)creating your own writable fork/copy of the project
in github side, fork upstream repository as your own(accessible) repository/remote of your fork
(b)in local desktop, clone remote of your fork to local as local copy of your fork. By default, locally there will be a origin repository as a remote and be a master branch like origin/master.
(c)create topic branch for changes you will make
(d)push commits from local branch of your fork to remote counterpart of your fork
sync local copy of my fork with upstream
(a)in local GitHub Desktop, configure a extra remote except origin, like upstream
here, take mongoengine project as an example,
```
git clone project_url_of_remote_of_your_fork
cd mongoengine
git remote -v #view current remotes with url, origin is at lease
git remote add remote_name remote_url_of_upstream #add subcommand
#if you fetch all commits that updstream made but you do not have
git fetch remote_name #like upstream
git checkout master #(optional)make sure current branch is on local copy master of my fork
git merge remote_name/master
git push origin master #update remote master branch of your fork
```
as for synchronizing/keeping up with upstream, two choices:(1)rebase your branch on top of whatever the target branch;(2)merge target branch into your branch.
Notes:
(1)fetch only downloads data to local, but not automatically merge it with any of you work or modidy what you are working on, that needs manual merge into your work.
Practice/in action
(1)squash action
for instance, some unpublished commits looks like
here, squash/combine lastest 2 commits into one by rebase command
(a)git rebase -i HEAD~2
and jump to editor window, like
(b)edit/modify/replace “pick” with “squash” or “s” at start of 2nd line,like squash e4704dc add main implementation
, save and quit, then jump to commit message editing window as optional.
until finished, by git log
, you will see the result resembling
as shown, a new commit as a substitute for two commits.
(2)revert commits
as for unpublished commits locally, take a same example with (1)
if back to commit_08ef39f without keeping local any changes, you can
git reset --hard 08ef39f
. Alternatively, you can keep local changes on current branch by first git stash save
, then execute reset command, finally continue your ongoing work by git stash pop stash@{num}
(3)undo partial changes for a single unstaged file
a common approach is with checkout command, below is a illustration where there are two changes and interactively discard one out,
(4)undo sth related with commits
situation that you commit too early and possibly forget to add some files, or you mess up your commit message and you want to try that commit again, you can
git commit -amend
for example, change “append print message” into “newly added log msg”
in pop-up text editor, you can replace the old message with new one and save quit, that after commit message is update and so is its SHA-1(checksum) number.
(5)undo some commits that had been pushed into GitHub
first, reset HEAD of local branch, like
git reset --hard SHA
#fallback to a certain commit before
secondly, update local new changes into GitHub
git push origin topic_branch -f
# -f option for non-fast forward