User Tools

Site Tools



This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revision Previous revision
Next revision
Previous revision
git_github_workflow [2019/04/04 12:32]
rpjday [Contributing changes]
git_github_workflow [2020/01/27 17:03] (current)
rpjday [Clone your personal fork to your local machine]
Line 1: Line 1:
 ===== Overview ===== ===== Overview =====
-Typical workflow for contributing to a public GitHub project, demonstrating the use of branches and remotes.+Typical workflow for contributing to a public GitHub project, demonstrating the use of branches and remotes. For this demonstration,​ I'll use a GitHub project I've been contributing to recently -- [[https://​​containers/​libpod]] -- which is the source of the Docker lookalike ''​podman''​ command (among other things).
-===== Steps in the workflow ​=====+===== Getting a GitHub Account ​=====
-==== Sample project ====+Unsurprisingly,​ if you don't already have a GitHub account, get one -- examples that follow will refer to my GitHub account ''​rpjday''​.
-Consider ''​progit/​progit2'',​ available [[https://​​progit/​progit2|here]] to which you can try to contribute to the ''​master''​ branch.+===== Standard GitHub workflow =====
-==== Fork the project ==== 
-Using your GitHub account, "​fork"​ a copy of the project, which will now be available as ''​rpjday/​progit2''​ [[https://​​rpjday/​progit2|here]]. 
-Note well that your fork of the project ​will //not// be updated from the upstream project that you forked; rather, your fork will be used as the source for "pull requests"​ that you want to contribute upstream. In short, commits go in only one direction %%--%% from your fork upstream, not vice versa.+==== Fork the project ​of interest ====
-==== Clone your fork to your local machine ====+As a first step, over at GitHub, you need to "fork" the public project of interest -- in this case, the public project ''​containers/​libpod''​ will be forked ​to a copy that I will own (also residing at GitHub), ''​rpjday/​libpod'',​ and here's the secret of the GitHub workflow.
-At this point, you want to make yet //another// copy of the repository ​%%--%% local clone of //your GitHub fork//; it'​s ​in this local clone where you will make all of the changes you want to contribute:+Once you create your personal fork of that public project ''​containers/​libpod''​, you will //not// update that personal copy from the public version, nor will you pull from your personal fork; rather, your personal fork will be used as the //​destination// ​to which you //push// branches with changes from your local machine that you will ask the ''​containers/​libpod''​ maintainers to pull from via "pull requests"​. 
 +So go ahead and create that personal GitHub fork before going any further. 
 +==== Clone your personal fork to your local machine ==== 
 +Once you've made that personal GitHub fork (agin, in my case, ''​rpjday/​libpod''​),​ you need to make one more copy of the repository -- this one will be a clone of your personal fork to your //local// machine, which represents the working tree in which you create new branches and make local changes that you'll push to your GitHub fork for eventual incorporation into the public project, but here'​s ​the trick for clarity. 
 +Since you'll (shortly) be working with two remotes for this workflow, when you clone your personal fork, select a remote name other than the default ​of ''​origin''​ -- I'll use the remote name of ''​rpjday'' ​to clearly identify that this is the remote corresponding to my personal fork over at GitHub, not the public project:
 <​code>​ <​code>​
-$ git clone https://​​rpjday/​progit2 pg2+$ mkdir podman/​libpod 
 +$ cd podman/​libpod 
 +$ git clone -o rpjday ​https://​​rpjday/​libpod git
 </​code>​ </​code>​
-Everything ​here is up to date with your GitHub fork:+Verify that everything ​here is up to date with your GitHub fork:
 <​code>​ <​code>​
 +$ cd git
 $ git status $ git status
 On branch master On branch master
-Your branch is up-to-date with 'origin/​master'​.+Your branch is up-to-date with 'rpjday/​master'​.
 nothing to commit, working tree clean nothing to commit, working tree clean
Line 34: Line 43:
 </​code>​ </​code>​
-andas you can see, your local clone has only one registered ​//remote//:+In addition, you can verify that your local clone has one registered remote ​-- your personal GitHub fork with remote name ''​rpjday''​:
 <​code>​ <​code>​
 $ git remote -v $ git remote -v
-origin https://​​rpjday/​progit2 ​(fetch) +rpjday https://​​rpjday/​libpod.git ​(fetch) 
-origin https://​​rpjday/​progit2 ​(push)+rpjday https://​​rpjday/​libpod.git ​(push)
 $ $
 </​code>​ </​code>​
-Note well that the remote ​''​origin'' ​is where you will push your contributions ​-- to your GitHub fork, not to the project ​to which you want to contribute.+Again, keep in mind that this remote is where you will push your intended ​contributions to the public ​project.
-==== Adding a remote for the main project ====+==== Adding a remote for the public ​project ====
-You now have to add a remote for the main project ​itselfsince that'​s ​where you'​ll ​be pulling any new commits from //anyone// contributing ​to the project (yourself or anyone else):+In addition ​to the remote for your personal fork, you need to register a //second// remote representing ​the public ​project, ​as this is where you'll //pull// new content from, including any of your pull requests that are accepted and merged into the public master branch. 
 +Again, for clarity, choose a remote name other than the default of ''​origin''​ -- I like to use the project ​name itself ​(in this case, ''​libpod''​):
 <​code>​ <​code>​
-$ git remote add progit ​https://​​progit/progit2+$ git remote add libpod ​https://​​containers/libpod
 $ $
 </​code>​ </​code>​
-Verify the new remote:+You can now verify that your local clone has two registered remotes -- one for pulling ​new content added to the public project (''​libpod''​),​ and the second your personal ​remote ​for pushing your submitted changes (''​rpjday''​):
 <​code>​ <​code>​
 $ git remote -v $ git remote -v
-origin https://​​rpjday/progit2 ​(fetch) +libpod https://​​containers/libpod ​(fetch) 
-origin https://​​rpjday/progit2 ​(push) +libpod https://​​containers/libpod ​(push) 
-progit https://​​progit/progit2 ​(fetch) +rpjday https://​​rpjday/libpod.git ​(fetch) 
-progit  ​https://​​progit/progit2 ​(push)+rpjday https://​​rpjday/libpod.git ​(push)
 $ $
 </​code>​ </​code>​
Line 68: Line 79:
 <​code>​ <​code>​
-$ cat .git/​config ​+$ cat .git/config
 [core] [core]
  repositoryformatversion = 0  repositoryformatversion = 0
Line 74: Line 85:
  bare = false  bare = false
  logallrefupdates = true  logallrefupdates = true
-[remote "origin"] +[remote "rpjday"] 
- url = https://​​rpjday/​progit2 + url = https://​​rpjday/​libpod.git 
- fetch = +refs/​heads/​*:​refs/​remotes/​origin/*+ fetch = +refs/​heads/​*:​refs/​remotes/​rpjday/*
 [branch "​master"​] [branch "​master"​]
- remote = origin+ remote = rpjday
  merge = refs/​heads/​master  merge = refs/​heads/​master
-[remote "progit"] +[remote "libpod"] 
- url = https://​​progit/progit2 + url = https://​​containers/libpod 
- fetch = +refs/​heads/​*:​refs/​remotes/​progit2/*+ fetch = +refs/​heads/​*:​refs/​remotes/​libpod/*
 $ $
 </​code>​ </​code>​
-==== Keeping up to date ====+==== Keeping up to date with public content ​====
-Before ​you even start contributing ​to the main project, there are three steps involved in keeping ​up with everyone else's contributions.+Even as you're working on contributions ​to the public ​project, there is undoubtedly new content being merged into its ''​master''​ branch from others, and you probably want to keep up with that new content in case you need to rebase any of your work on top of it.
-First, fetch from the upstream ''​progit''​ remote into the remote tracking branch ''​progit/​master'':​+First, you can, as often as you like, fetch from the upstream ​(public project) ​''​libpod''​ remote into your remote tracking branch ''​libpod/​master'' ​with
 <​code>​ <​code>​
-$ git fetch progit+$ git fetch libpod
 </​code>​ </​code>​
-Nextmanually ​merge any new content into your local ''​master''​ branch:+Occasionallyyou might want to merge that new content into your local ''​master''​ branch ​in case you need to do any local rebasing:
 <​code>​ <​code>​
-$ git merge progit/master+$ git checkout master 
 +$ git merge libpod/master
 </​code>​ </​code>​
-Finally, push this new content ​to your GitHub ​fork of the project:+Finally, ​whenever you update your local master branch, you should ​push it to your personal ​fork (which is how your personal fork at GitHub gets updated):
 <​code>​ <​code>​
-$ git push origin ​master+$ git push rpjday ​master
 </​code>​ </​code>​
 Do all of this on a regular basis to keep everything in sync. Do all of this on a regular basis to keep everything in sync.
-==== Contributing changes ====+===== Contributing changes ​=====
-Contributing changes to the main project involves three steps:+==== The general steps in contributing changes ==== 
 +Contributing changes to the public GitHub ​project involves three steps:
   * Make and commit some //local changes// (preferably on a feature branch).   * Make and commit some //local changes// (preferably on a feature branch).
-  * Push those changes (that branch) to your GitHub fork. +  * Push those changes (that branch) to your personal ​GitHub fork. 
-  * Make a "pull request"​ to have the main project accept your commit(s) ​on that branch.+  * Over at GitHub, make a "pull request"​ to have the main project accept your changes ​on that branch. 
 +==== Making some local changes ====
-Firstcreate ​a new branch, make and commit ​silly change:+For each set of related changesstart a new feature ​branch ​with distinct name that reflects what that branch is doing:
 <​code>​ <​code>​
-$ git checkout -b topic/rpjday/issue42 +$ git checkout -b rpjday/README_changes 
-Switched to a new branch 'topic/rpjday/issue42'+Switched to a new branch '​rpjday/​README_changes'
 $ $
 </​code>​ </​code>​
-Make a simple change ​to ''​README.asc''​ and commit ​it:+For our example, make some trivial changes ​to the top-level ​''​'' ​file, and locally ​commit ​those changes on that branch:
 <​code>​ <​code>​
-$ git checkout ​-b topic/rpjday/issue42 +$ git commit ​-a -m "​​ silly changes"​ 
-Switched to a new branch '​topic/​rpjday/​issue42'​+[rpjday/README_changes b1a09348] silly changes 
 + 1 file changed, 4 insertions(+)
 $ $
 </​code>​ </​code>​
 +==== Pushing your work ====
 +You can continue adding and committing (related) work to this feature branch and, once you're satisfied, you can push that branch to your personal GitHub fork with:
 <​code>​ <​code>​
-$ git commit -a -m "fix issue42"​ +$ git push rpjday rpjday/README_changes
-[topic/rpjday/issue42 77fad5f] topic/rpjday/issue42 +
- 1 file changed, 1 insertion(+),​ 1 deletion(-) +
 </​code>​ </​code>​
-<​code>​ +==== And over At GitHub ====
-$ git show +
-commit 77fad5f0aadd229628baa7811b0b49c7580d96f0 (HEAD -> topic/​rpjday/​issue42) +
-Author: Robert P. J. Day <​>​ +
-Date:   Wed Feb 14 07:06:42 2018 -0500+
-    fix issue42+Provided you're logged into your account at GitHub, you'll suddenly see the appearance of a new branch ''​rpjday/​README_changes''​. If you think it's ready to go, you can select "​Compare & pull request"​ to examine and confirm that you want to hand that off to the main project.
-diff --git a/​README.asc b/​README.asc +If all goes well and your change is accepted and committed (in this caseinto the ''​master''​ branch)you will have to perform ​the two earlier steps to fetch and merge your changes into your local clone into the ''​master''​ branch: 
-index d7810fd..126bfd4 100644 + 
---- a/​README.asc +<​code>​ 
-+++ b/​README.asc +git fetch libpod 
-@@ -1,4 +1,4 @@ +$ git merge libpod/​master
--= Pro Git, Second Edition +
-+= Pro Git, Second Edition (rday change) +
-  +
- ​Welcome ​to the second edition of the Pro Git book. +
-  +
 </​code>​ </​code>​
-At this point, you can push this new branch to your GitHub fork:+In addition, if you have no further need of that local feature, you can delete it:
 <​code>​ <​code>​
-$ git push origin topic/rpjday/issue42+$ git branch -d rpjday/README_changes
 </​code>​ </​code>​
-==== And over At GitHub ​====+==== Adjusting your local branch ​====
-Provided you're logged into your account at GitHub, you'll suddenly see the appearance of a new branch ​''​sillyb''​. If you think it's ready to goyou can select "​Compare & pull request"​ to examine and confirm ​that you want to hand that off to the main project. +Given the possibility that your pull request might provoke some comments about possible improvements, you can make those local improvements,​ stage them and commit them on the same branch ​as beforethen force push that branch ​to replace ​the older one:
- +
-If all goes well and your change is accepted and committed, you will have to perform the two earlier steps to fetch and merge your changes into your local clone into the ''​master''​ branch:+
 <​code>​ <​code>​
-$ git fetch progit +$ git push -f rpjday rpjday/README_changes
-$ git merge progit/master+
 </​code>​ </​code>​
-In addition, you can now delete the ''​sillyb''​ branch if you have no further use for it. 
git_github_workflow.1554381160.txt.gz · Last modified: 2019/04/04 12:32 by rpjday