GitHub workflow according to Google Golosova Marina
Git after Subversion: unsafe history Subversion stores commit history as it was written originally. Once committed – lasts forever. Good for credibility, pain for perfectionism. In Git the commit history can be rewritten or removed – and not only locally, but also in the central (remote) repository. Good for perfectionism, dangerous for associates. Unstable history is the main reason why GitHub is not friendly to the commit notifications by e-mail git push != svn commit == merged pull request 01.06.2017
Workflow v.01.06.2017 01.06.2017
Workflow (1) Original Fork Local push push push push Request accepted and merged GitHub: pull request 6.1 6.5 Stable Branch (readonly) Changes required MyChanges2 Original git pull upstream or git pull 6.1 6.2 1.1 GitHub: fork git push –u origin MyChanges2 5 7 push Stable Branch (writable copy) MyChanges Draft MyChanges1 Fork push push push git push --force 1.2 8 5 Working (draft) Branch (+N commits) Working (fair) Branch (rebase -i) 6.4 Working (fair) Branch (rebase -i) Stable Branch (local copy) Local 4.1 2 git clone <fork> git remote add upstream <original> or git clone <original> <commitA> 4.1 git branch new-branch git checkout new-branch or git checkout –b new-branch git commit // <commitB> git commit // <commitC> … git commit // <commitX> git checkout –b fair-branch1 git rebase –i <commitA> pick <commitA> edit <commitB> drop <commitC> pick <commitD> squash <commitE> fixup <commitF> … git checkout –b fair-branch2 git rebase –i <commitA> drop <commitA> drop <commitB> pick <commitC> drop <commitD> drop <commitE> drop <commitF> … git commit … [git rebase -i] 6.3 3 4.2 01.06.2017 4.2
Workflow (2) Create local copy: Fork (via GitHub) (optionaly) Clone (locally) Add upstream (for fork) Create a working branch for your changes see: why not to work in the “original” branch, Slide 14 Commit your changes locally see: when to push your changes to GitHub, Slide 15 Make-up the commit history Create a new “fair” branch if there are more changes in the working branch than needed for one pull request if you’re going to keep on working in the branch after the pull request is sent Use rebase –i to rewrite the commit history Push the “fair” branch to GitHub 01.06.2017
Workflow (3) Pull request Create request via GitHub If the reviewer ask you for changes: go the local “fair” branch make changes required rewrite the history (if needed) push new commits to GitHub (use --force, if the previously pushed part of the history was changed) … Request is accepted and merged to the stable branch: Rebase + merge (fast-forward merge) for obvious cases (when there were no changes in the branch in parallel to the request Merge (with merge commit) when fast-forward is not applicable without rebase Squash (???) is not an option Remove the remote request branch (at least in the original repository) 01.06.2017
Workflow (4) Update local copy Update fork repository git pull [upstream (for fork case)] Update fork repository git push 01.06.2017
Git Keywords 01.06.2017
Keywords Pull – take (fetch) actual version from remote repository and merge local changes with it Push – put local commits to remote repository Push --force – overwrite remote history and current state with local version. To be used only in personal temporary branches (like those for pull request). Pull request – “I have some good commits here, please add (pull) them to the stable branch” Original / central repository – PanDAWMS/dkb Fork repository – mgolosova/dkb (copy of the PanDAWMS/dkb on the GitHub side) 01.06.2017
Keywords: rebase Rebase {<commit> | <branch>} – rewrite the history (reapply commits on top of another base tip) HEAD – “you-are-here”, last commit in the current branch <commit>~<N> -- N commits earlier than <commit> A---B---C topic / D---E---F---G master A'--B'--C' topic / D---E---F---G master git rebase master topic o---o---o---o---o master \ o---o---o---o---o next o---o---o topic o---o---o---o---o master | \ | o'--o'--o' topic \ o---o---o---o---o next git rebase --onto master next topic git rebase --onto topicA~5 topicA~3 topicA E---F---G---H---I---J topicA E---H'---I'---J' topicA 01.06.2017
Keywords: rebase rebase –i <commit> Interactive rebase Rewrite the history: reorder commits, drop them, edit, squash – whatever 01.06.2017
Keywords: reset <=> Reset <commit> git reset --soft HEAD~1 set HEAD to <commit> (--soft) remove changes between <commit> and last commit made before reset from index (--mixed) (default) rewrite working directory to <commit> version (--hard) git reset --soft HEAD~1 vi myFile.txt git add myFile.txt git commit vi myFile.txt git add myFile.txt git commit --amend <=> More info: https://git-scm.com/ 01.06.2017
Why & When 01.06.2017
Why …(not) to fork the repository? …not to work in a local copy of the original branch? no merge problems when pull actual version from the original repository there`s always a branch in the actual state to branch off of less possibility to erroneously push to the original …not to use push --force anywhere but your own working space (temporary commit branches, personal development branches, fork repository…)? when the remote repository forcefully updated, the existing commit history can be rewritten if your local copy is behind the remote version, you forceful update will erase someone else`s work (--force-with-lease helps here) if someone has already pulled the previous history version and started to work on it, in the future the updated remote version might be harmful for the local changes …(not) to fork the repository? (+) less temporary branches in the original repository Lots of branches looks like a mess, but: temporal working branches are to be removed after pull request (shall we use some prefix for them?) pull request branches are to be removed after merge human-related branches – our team is not so big to make it a problem (-) extra work to keep the fork up to date (pull upstream + push to fork every now and then) (-) no one can see if you`re working hard or do nothing without checking your fork version intentionally 01.06.2017
When …to push to the remote repository? …to create a pull request? work is finished work is not finished, but you believe that a part of it is successfully done and want to “isolate” this part from the next one logically you want to declare “I`m working on it, here`s the current state” …to create a pull request? work is not finished, but you want to ask someone for review and discuss your course (do not forget to add [WIP] (work in progress) marker (tag, or prefix to the request title)) 01.06.2017
That`s it 01.06.2017