====== Using git ====== git is a general purpose version control system that supports numerous workflows. This document discusses two key ways to use git. * Testing Workflow - For testers who won't be making changes. * Developer Workflow (Fork) - If you will be making changes. ===== Testing Workflow ===== If you don't plan on submitting code changes, you can track development using just a few git commands. First, you'll want to make a clone of the git repo on your local machine. This is similar to "svn checkout". git clone git://git.code.sf.net/p/rosegarden/git rosegarden-git That will create a rosegarden-git directory where you can build and test as usual. See the README in that directory for build instructions. cd rosegarden-git less README If you want to get the latest, you can pull. This is similar to "svn update". git pull --tags To examine your local copy of the history, use git log. git log Or even nicer is the gitk GUI. gitk & And that should be everything you need for testing and using the latest. Questions are always welcome on the users mailing list. ===== Developer Workflow (Fork) ===== //A note on learning git... With git it helps to understand a little about the internals. E.g. the fact that it is just a branching linked list of commits. Then it starts to make sense. Also playing with a small experimental repo can build confidence quickly.// Before you use git for the first time, you must tell it your name and email address. git config --global user.name "Joe Smith" git config --global user.email j.smith@gmail.com This will appear in all of your commits, so make sure it's correct. Next, you'll need to fork the repo you want to work on. This makes a public copy that can only be modified by you. In sourceforge, click the "fork" link in the left column of the code viewer. https://sourceforge.net/p/rosegarden/git/ci/master/tree/ It will allow you to set the home project (use the default which is your sourceforge userid), the label (this is the unique name that appears in your profile), and the mount point (the name in the URL it creates). Just go with defaults for your first fork. Usually, defaults will be fine. The fork will take a while. It is making a copy of the entire 150+MB rosegarden repo for your personal use on the sourceforge servers. Then it is analyzing that copy which takes a minute or so. Wait a few moments and do a refresh and the repo should appear. Now you can clone it using "ssh" protocol so you can write (push) to it. Use the command that appears in the "Read/Write SSH access" box to do your clone. It will look something like this: git clone ssh://tedfelix@git.code.sf.net/u/tedfelix/rosegarden rosegarden-git That will create a local "rosegarden-git" directory that you can build and test from. And since this will be connected to your remote fork, you can make changes locally and push them to the remote server as well. From here on out we'll assume you are in your local rosegarden-git directory. cd rosegarden-git As a final step, you'll need to configure a remote called "upstream" so that you can stay in sync with the official Rosegarden repo. git remote add upstream git://git.code.sf.net/p/rosegarden/git After that you should have two remotes configured appropriately: $ git remote -v origin ssh://tedfelix@git.code.sf.net/u/tedfelix/rosegarden (fetch) origin ssh://tedfelix@git.code.sf.net/u/tedfelix/rosegarden (push) upstream git://git.code.sf.net/p/rosegarden/git (fetch) upstream git://git.code.sf.net/p/rosegarden/git (push) Now you are ready to make changes. ==== Making Changes ==== Before making any changes, make sure you are on the right branch with ''git status''. $ git status On branch master Your branch is up to date with 'origin/master'. Currently we are on the ''master'' branch. You should never commit changes to ''master''. But at some point it will happen and fortunately it's relatively easy to fix. (See "Committing to the Wrong Branch" below.) For now let's assume we are doing things the Right Way and we are going to work in a new branch. Let's say we want to do some work on bug #123. Before we begin we create a local ''bug123'' branch to work in and base it on ''master'': $ git checkout -b bug123 master Switched to a new branch 'bug123' This creates the new local branch and checks it out. Use git status to make sure you are where you think you are: $ git status On branch bug123 nothing to commit, working tree clean Now you can make changes and commit them to your local bug123 branch. As with svn, you can use "git status" to see what you have changed: $ git status On branch bug123 Changes not staged for commit: (use "git add ..." to update what will be committed) (use "git restore ..." to discard changes in working directory) modified: README no changes added to commit (use "git add" and/or "git commit -a") git diff provides all the details. $ git diff diff --git a/README b/README index b17b6c4a5..f93535a00 100644 --- a/README +++ b/README @@ -139,7 +139,7 @@ data/appdata. It is named rosegarden.appdata-old.xml. Authors and copyright --------------------- -Rosegarden is Copyright 2000-2020 The Rosegarden Development Team +Rosegarden is Copyright 2000-2021 The Rosegarden Development Team See http://rosegardenmusic.com/resources/authors/ for a complete list of developers past and present, and to learn something about the history of our Or get a summary with "--stat". $ git diff --stat README | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) When you are ready to commit to your local git repo, use git add/rm and git commit. $ git add . $ git status On branch bug123 Changes to be committed: (use "git restore --staged ..." to unstage) modified: README $ git commit [bug123 7e717ac63] Update README 1 file changed, 1 insertion(+), 1 deletion(-) The git book covers all of this in far more detail: https://git-scm.com/book/en/v2/Git-Basics-Recording-Changes-to-the-Repository ==== Merge Request ==== Once your changes are ready to be incorporated into the project, you'll want to push them from your local repo (fork) to your remote fork on sourceforge (origin). Make sure you are on the correct branch. In this case, bug123: git checkout bug123 The first time you push a local branch to your remote fork, you will need to set the local branch's "upstream" to ''origin'' (your remote fork) and specify the name for the new remote branch: git push -u origin bug123 Git will confirm that the push was successful and that the upstream was set: To ssh://git.code.sf.net/p/rosegarden/git * [new branch] bug123 -> bug123 Branch 'bug123' set up to track remote branch 'bug123' from 'origin'. Git remembers the upstream and will use it the next time you push. There is no need to specify ''-u origin bug123'' again: git push Now you can send a merge request to the owner of the original repo that you forked. On the sourceforge website, bring up your fork and click on the "Request Merge" link in the left column in sourceforge's code viewer. Then fill in the summary and an optional description. Source Branch for this example would be "bug123". Target Branch would probably be "master". The owner of the original repo will then get the merge request and decide what to do with it. //Note that with git the term "upstream" is used for two different things. Most commonly it's used to refer to the remote branch that a local branch will push to. It's also used to refer to the remote repo that was the source of your fork.// ==== Branching ==== Branching is so easy with git that it's not unusual to end up doing work on the wrong branch. Use git status frequently to confirm which branch you are on. Then switch to the right one before continuing. Switching local branches is simply a checkout. $ git checkout master Switched to branch 'master' Your branch is up to date with 'origin/master'. $ git checkout bug123 Switched to branch 'bug123' Your branch is up to date with 'origin/bug123'. Check which local branch you are on with git status. $ git status On branch bug123 Your branch is up to date with 'origin/bug123'. nothing to commit, working tree clean You can list your local branches. $ git branch -v * bug123 7e717ac63 Update README master f04c831e0 cmake: Pre-compiled header comments And examine your remote branches. $ git remote show origin * remote origin Fetch URL: ssh://tedfelix@git.code.sf.net/p/rosegarden/git Push URL: ssh://tedfelix@git.code.sf.net/p/rosegarden/git HEAD branch: master Remote branches: bug123 tracked master tracked Local branches configured for 'git pull': bug123 merges with remote bug123 master merges with remote master Local refs configured for 'git push': bug123 pushes to bug123 (up to date) master pushes to master (up to date) ==== Resyncing master ==== While working with branches, don't forget to periodically fetch the latest changes to master from the upstream repo and push to resync your fork's master. First switch to master and make sure the working directory is clean and up to date: $ git checkout master Already on 'master' Your branch is up to date with 'origin/master'. $ git status On branch master Your branch is up to date with 'origin/master'. nothing to commit, working tree clean If it isn't clean and up to date, you'll want to fix that before continuing. Otherwise a ''git pull'' will make a mess of things. Assuming master is clean and up to date you can resync your master and your fork's master with a pull from upstream and a push to origin: git pull --tags upstream master git push --tags origin master ==== Deleting a Remote Branch ==== To delete a branch from your remote fork on sourceforge (origin): $ git push origin --delete bug123 remote: refresh queued. To ssh://git.code.sf.net/p/rosegarden/git - [deleted] bug123 ==== Deleting a Local Branch ==== To delete a local branch, first make sure you don't have it checked out. Switching to master is safe: git checkout master Then use ''git branch -d'': $ git branch -d bug123 Deleted branch bug123 (was 7e717ac63). Depending on whether it thinks commits may be lost, git might require you to specify ''-D'' to force the delete. Make sure nothing will be lost before using ''-D''. ==== Creating a Safety Branch ==== And finally, if you're about to go through some scary git commands on a branch, you can always drop a safety branch that you can get back to at any time. git branch my-safety-branch1 ... (lots of scary git commands like ''git reset'' and ''git branch -D'') git checkout my-safety-branch1 ==== Committing to the Wrong Branch ==== It happens to all of us at some point. This is where you can learn more about the internals of git. Git implements its change history as a branching linked list pointing into the past. As such, we can manipulate it in almost any way we want. Let's say we accidentally committed something to master that should have been committed into a new branch. $ git commit -am "Update README" [master 556976f7d] Update README 1 file changed, 1 insertion(+), 1 deletion(-) Oops. Ok, not a problem. Let's drop the branch we wanted to create here: git branch bug222 Listing the branches we see that master and bug222 are in the same place. $ git branch -v bug222 556976f7d Update README * master 556976f7d [ahead 1] Update README Also note that master is ahead by one commit that shouldn't be there. So we need to move our local master back one commit. There are a couple of ways to do that. But the one that makes the most sense is to put master back where it belongs at origin/master: $ git reset --hard origin/master HEAD is now at f04c831e0 cmake: Pre-compiled header comments Now check the branches: $ git branch -v bug222 556976f7d Update README * master f04c831e0 cmake: Pre-compiled header comments That looks better. Now we can switch to the bug222 branch where we should have been: $ git checkout bug222 Switched to branch 'bug222' For handling more complex situations, look into the [[https://git-scm.com/docs/git-cherry-pick|git cherry-pick command]]. ==== Resources ==== github has some good documentation on forking: https://docs.github.com/en/github/getting-started-with-github/fork-a-repo If you want to go even deeper into git, the git book will take you there: [[https://git-scm.com/book/en/v2]] Definitely read it after you are done with this. The [[https://www.oreilly.com/library/view/version-control-with/9781449345037/|O'Reilly Git Book]] is pretty good as well.