{"id":59,"date":"2023-09-18T21:18:04","date_gmt":"2023-09-18T11:18:04","guid":{"rendered":"http:\/\/www.cheerfulprogramming.com\/?p=59"},"modified":"2023-09-18T21:18:04","modified_gmt":"2023-09-18T11:18:04","slug":"git-workflow","status":"publish","type":"post","link":"http:\/\/www.cheerfulprogramming.com\/?p=59","title":{"rendered":"Git Workflow"},"content":{"rendered":"<h1>Introduction<\/h1>\n<p>Git is widely-used and is a very powerful tool for version control of computer code.  It is not particularly easy or intuitive to use, however with a few simple commands you can get productive fairly quickly.<\/p>\n<h1>Joining a project<\/h1>\n<p>You will typically join a project on a code repository such as GitHub or Bitbucket by cloning it with a Linux command such as:<\/p>\n<pre><code class=\"\" data-line=\"\">git clone https:\/\/repo-home-url\/project.git<\/code><\/pre>\n<p>This will download the code and automatically configure your local copy of the reposity to point back to the repository website as its <code class=\"\" data-line=\"\">origin<\/code> repository.<br \/>\nSee <a href=\"https:\/\/docs.github.com\/en\/repositories\/creating-and-managing-repositories\/cloning-a-repository\" title=\"GitHub\">GitHub<\/a> for examples and screenshots.<\/p>\n<h1>Start a new piece of work<\/h1>\n<p>Normally when fetching the latest changes that your colleagues have made to a project you will need to be on the <code class=\"\" data-line=\"\">master<\/code> branch.  Then you can pull the changes from master.  If you cloned the repository with Git then it should already be configured to know where its <code class=\"\" data-line=\"\">origin<\/code> is.  I usually combine two commands with the <code class=\"\" data-line=\"\">&amp;&amp;<\/code> as shown so that if the first command fails the next one will not attempt to run.<\/p>\n<pre><code class=\"\" data-line=\"\">git checkout master &amp;&amp; git pull origin master<\/code><\/pre>\n<p>Then you will create a branch for your work:<\/p>\n<pre><code class=\"\" data-line=\"\">git checkout -b my-branch-name<\/code><\/pre>\n<p>Typically <code class=\"\" data-line=\"\">my-branch-name<\/code> will have in it some ticket number (if you use a work ticketing system), possibly your name, and maybe a concise description of the work.  Your team leader will help you understand the conventions that your team uses, and any automatic workflow integrations the team has set up between your repository and your ticketing system.  For example, it is possible to set up integrations between Phabricator (for code reviews) and JIRA (for tickets) so that when you create a pull request (PR) on Phabricator it updates the ticket status on JIRA, and then when the PR is landed on Phabricator it updates JIRA again.<\/p>\n<h1>Save some changes<\/h1>\n<p>Next you will do your work and commit it in small but meaningful changes.  If you change a file <code class=\"\" data-line=\"\">some_code.py<\/code> you will commit it like this:<\/p>\n<pre><code class=\"\" data-line=\"\">git add some_code.py\ngit commit -m &quot;Add a new function which does something cool.&quot;<\/code><\/pre>\n<p>It is a good idea to group related changes together in a single commit, even if they span multiple files.  It is possible in Git to commit only some changes to a file instead of every change to the file, although this is usally more easily done using graphical tools that are commonly available in integrated development environments (IDEs) such as VS Code, IntelliJ IDEA, or Eclipse.  Ideally your commit should not break any existing code.  You can see all your changes on your branch (which is based on <code class=\"\" data-line=\"\">master<\/code>) with<\/p>\n<pre><code class=\"\" data-line=\"\">git log master.. --oneline<\/code><\/pre>\n<p>Don&#8217;t forget the two dots (<code class=\"\" data-line=\"\">..<\/code>)!  If you want to see the three most recent commits in the branch, run<\/p>\n<pre><code class=\"\" data-line=\"\">git log HEAD~3.. --oneline<\/code><\/pre>\n<p>Omit the <code class=\"\" data-line=\"\">--oneline<\/code> argument to see more details.  The <code class=\"\" data-line=\"\">git log<\/code> command has many options which provide powerful tools to analyse changes on a branch.<\/p>\n<p>When you have finished making changes, run your test suite to make sure that you haven&#8217;t broken anything.  When it passes it is time to push your changes up for code review by one of your peers, or the project owner.  Run<\/p>\n<pre><code class=\"\" data-line=\"\">git push origin my-branch-name<\/code><\/pre>\n<p>This will create a branch on the remote server with <code class=\"\" data-line=\"\">my-branch-name<\/code>.  For tracking your remote branches it is easiest if you use the same name for your remote branch as your local branch.  At this point your code reviewer may have suggestions which require you to make some more commits.  Make them and then push again with the command above.<\/p>\n<h1>Staying up-to-date<\/h1>\n<p>You may find, while you are working on your branch or implementing suggestions by your code reviewer, that your branch has become out of date with the <code class=\"\" data-line=\"\">master<\/code> branch, in which case you could get merge conflicts when you try to land your PR.  This is a normal part of team work in a software development team.  Rectify the conflicts as follows, but first ensure that you have no uncommitted changes in your local repository.<br \/>\nIf you have work in progress that you don&#8217;t wish to commit but you don&#8217;t wish to discard either, stash it:<\/p>\n<pre><code class=\"\" data-line=\"\">git stash<\/code><\/pre>\n<p>You can unstash it at any time with<\/p>\n<pre><code class=\"\" data-line=\"\">git stash pop<\/code><\/pre>\n<p>When you are ready to rebase, remembering to have a clean local repo with no uncommitted changes, do:<\/p>\n<pre><code class=\"\" data-line=\"\">git checkout master &amp;&amp; git pull origin master\ngit rebase master my-branch-name<\/code><\/pre>\n<p>Git will try to replay your changes on top of the latest master.  If there are merge conflicts it will stop and force you to fix them before proceeding.  If you make a mistake and want to start again, run<\/p>\n<pre><code class=\"\" data-line=\"\">git rebase --abort<\/code><\/pre>\n<p>Otherwise make your changes and run<\/p>\n<pre><code class=\"\" data-line=\"\">git add . &amp;&amp; git rebase --continue<\/code><\/pre>\n<p>as many times as necessary until rebase is complete.  Notice that you don&#8217;t do <code class=\"\" data-line=\"\">git commit<\/code> during rebase!  All you need to do is make the changes to the files and Git will save them with the current commit as it works through every change in your branch.  If you want to do an interactive rebase, so that you can squash a few commits together, leave out some commits, or re-order them, do<\/p>\n<pre><code class=\"\" data-line=\"\">git rebase -i master my-branch-name<\/code><\/pre>\n<p>This will open up your default text editor and provide you instructions on how to proceed.  When you have finished, push your changes up to the remote server again.  If the standard <code class=\"\" data-line=\"\">git push<\/code> command shown earlier does not work, you may need to force push, as follows:<\/p>\n<pre><code class=\"\" data-line=\"\">git push origin my-branch-name --force<\/code><\/pre>\n<p>That should get you started with a simple Git workflow.  Git is not particularly user-friendly, but it is very powerful and has a lot of features.  It is also widely used so it is worth learning.  <\/p>\n<h1>Learning more<\/h1>\n<p>To get more help from Git you can view the man pages or print the help, as shown in the following examples:<\/p>\n<pre><code class=\"\" data-line=\"\">man git-pull\ngit push --help<\/code><\/pre>\n<h1>Acknowledgements<\/h1>\n<p>The author acknowledges the traditional custodians of the Daruk and the<br \/>\nEora People and pays respect to the Elders past and present.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Introduction Git is widely-used and is a very powerful tool for version control of computer code. It is not particularly easy or intuitive to use, however with a few simple commands you can get productive fairly quickly. Joining a project You will typically join a project on a code repository such as GitHub or Bitbucket [&hellip;]<\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[2],"tags":[],"class_list":["post-59","post","type-post","status-publish","format-standard","hentry","category-git"],"_links":{"self":[{"href":"http:\/\/www.cheerfulprogramming.com\/index.php?rest_route=\/wp\/v2\/posts\/59","targetHints":{"allow":["GET"]}}],"collection":[{"href":"http:\/\/www.cheerfulprogramming.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/www.cheerfulprogramming.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/www.cheerfulprogramming.com\/index.php?rest_route=\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"http:\/\/www.cheerfulprogramming.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=59"}],"version-history":[{"count":0,"href":"http:\/\/www.cheerfulprogramming.com\/index.php?rest_route=\/wp\/v2\/posts\/59\/revisions"}],"wp:attachment":[{"href":"http:\/\/www.cheerfulprogramming.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=59"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/www.cheerfulprogramming.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=59"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/www.cheerfulprogramming.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=59"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}