Differences

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
dev:using_git [2009/11/25 22:04]
hjunes git svn was too slow. delete the experiment.
dev:using_git [2022/05/06 16:07] (current)
Line 1: Line 1:
-Before continuing to read this page, you have two options: +====== Using git ======
-  - If you are happy with using svn, stop reading here. +
-  - If you would like to experiment with git, continue reading.+
  
-This page has been benefited lot from the following pages: +git is general purpose version control system that supports numerous workflows This document discusses two key ways to use git.
-  * [[http://www.viget.com/extend/effectively-using-git-with-subversion/|Effectively Using Git With Subversion]]+
  
-=====Installing git=====+  * Testing Workflow - For testers who won't be making changes. 
 +  * Developer Workflow (Fork) - If you will be making changes.
  
-Install first git and a graphical client (e.g. gitk) for it +===== Testing Workflow =====
-<code> +
-sudo apt-get install git gitk +
-</code>+
  
-=====Applying git clone to the svn repository===== +If you don't plan on submitting code changes, you can track development using just a few git commands.
-Create the following ''git-clone-rg-repository.sh'' script in order to clone the repository +
-<code+
-#!/bin/bash +
-USERNAME=<username> +
-ERROR_CODE=-1 +
-while [ $ERROR_CODE -ne 0 ]; do +
-  # repeat until final success +
-  git svn clone -s https://${USERNAME}@rosegarden.svn.sourceforge.net/svnroot/rosegarden rosegarden.git +
-  # it may be possible that the commands ends to an error like 'RA layer request failed:' +
-  let ERROR_CODE=$? +
-  # just a small pause before repeating the command +
-  sleep 1 +
-done +
-echo Finished. +
-</code> +
-The clone the repository (takes a long, long time (several, or, even tens of hours) and 662 Mb to fetch all branches) by running the script +
-<code> +
-bash ./git-clone-rg-repository.sh +
-</code> +
-If the script still fails, end the loop by pressing Ctrl+C and rerun the script.+
  
-=====Example commit 1: Generating .gitignore and adding it to the subversion repository===== +First, you'll want to make a clone of the git repo on your local machine.  This is similar to "svn checkout".
-(These lines have already been executed once.)+
  
-==== Generating .gitignore ====+  git clone git://git.code.sf.net/p/rosegarden/git rosegarden-git
  
-Generate the ignore file with +That will create a rosegarden-git directory where you can build and test as usual See the README in that directory for build instructions.
-<code> +
-cd rosegarden.git +
-git-svn show-ignore > .gitignore +
-</code>+
  
-==== Adding file to a following local commit ====+  cd rosegarden-git 
 +  less README
  
-Add the generated file to the local commit +If you want to get the latest, you can pull.  This is similar to "svn update".
-<code> +
-git add .gitignore +
-</code> +
-and check the status of the repositoryif you wish +
-<code> +
-git status +
-</code> +
-the following lines will result +
-<code> +
-# On branch master                                          +
-# Changes to be committed:                                  +
-#   (use "git reset HEAD <file>...to unstage)             +
-#                                                           +
-#       new file:   .gitignore                              +
-#     +
-</code>+
  
-==== Committing locally ====+  git pull --tags
  
-Commit locally the changes +To examine your local copy of the history, use git log.
-<code> +
-git commit .gitignore +
-</code> +
-write then the comment +
-<code> +
-Add .gitignore file as a result of the following command: +
- git svn show-ignore > .gitignore +
-</code> +
-after writing the comment, save the file in editor and finally quit the editor. +
-This will commit locally the changes and the following information will be given +
-<code> +
-Created commit 4dcfaa7: Add .gitignore file as a result of the following command: +
- 1 files changed, 181 insertions(+), 0 deletions(-)                               +
- create mode 100644 .gitignore                                                    +
-</code>+
  
-==== Fetching latest changes before commit ====+  git log
  
-Before committing, you want make sure that you have the latest version of the source +Or even nicer is the gitk GUI.
-<code> +
-git svn rebase +
-</code> +
-Invoking the above command +
-  - reverts temporarily the changes you have made +
-  - downloads all changes from subversion,  +
-  - applies the downloaded changes from subversion to the previous version downloaded from subversion, and +
-  - applies again the changes you have made. +
-The following lines will be printed +
-<code> +
-First, rewinding head to replay your work on top of it...                         +
-Applying: Add .gitignore file as a result of the following command:               +
-</code>+
  
-==== Committing back to subversion ====+  gitk &
  
-Suggesting that there were no code to merge and no conflicts to solve, you can then commit back to subversion +And that should be everything you need for testing and using the latest.  Questions are always welcome on the users mailing list.
-<code> +
-git svn dcommit +
-</code> +
-You will see then the following output +
-<code> +
-Committing to https://hjunes@rosegarden.svn.sourceforge.net/svnroot/rosegarden/trunk ... +
-        A       .gitignore                                                               +
-Committed r10792                                                                         +
-        A       .gitignore                                                               +
-r10792 = 8d3f93067b542f7e770c08a3e84c8fb4bb8fb46f (trunk)                                +
-No changes between current HEAD and refs/remotes/trunk                                   +
-Resetting to the latest refs/remotes/trunk                                               +
-</code> +
-As you can see, the commit has been assigned subversion's version number 10792.+
  
-===== A typical short working cycle =====+===== Developer Workflow (Fork) =====
  
-First you check for new updates +//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.//
-<code> +
-git svn rebase +
-</code>+
  
-Then you make your changes, compile and test +Before you use git for the first time, you must tell it your name and email address.
-<code> +
-[... editing ...] +
-make +
-./rosegarden +
-</code>+
  
-Now lets prepare for the commitFirst lets see what changes we are going to commit +  git config --global user.name "Joe Smith"  
-<code> +  git config --global user.email j.smith@gmail.com
-git diff +
-</code>+
  
-Add files which were changed and commit them locally +This will appear in all of your commits, so make sure it's correct.
-<code> +
-git add [file1 file2 ...] +
-git commit -m "Message..." +
-</code>+
  
-Then one more check for probable new set of changes +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.
-<code+
-git svn rebase +
-</code> +
-No merge was needed in this example.+
  
-Finally, submit the changes +https://sourceforge.net/p/rosegarden/git/ci/master/tree/
-<code> +
-git svn dcommit +
-</code>+
  
-That was it. The above set of commands is not optimalbut it works.+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.
  
-===== Using TEMPORARILY branch =====+The fork will take 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.
  
-First you may want to **fetch** (the code word) the changes in all branches +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 (pushto it.  Use the command that appears in the "Read/Write SSH access" box to do your clone.  It will look something like this:
-<code> +
-git svn fetch +
-</code>+
  
 +  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''.
 +
 +<file>
 +$ git status
 +On branch master
 +Your branch is up to date with 'origin/master'.
 +</file>
 +
 +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:
 +
 +<file>
 +$ git status
 +On branch bug123
 +Changes not staged for commit:
 +  (use "git add <file>..." to update what will be committed)
 +  (use "git restore <file>..." to discard changes in working directory)
 + modified:   README
 +
 +no changes added to commit (use "git add" and/or "git commit -a")
 +</file>
 +
 +git diff provides all the details.
 +
 +<file>
 +$ 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
 +</file>
 +
 +Or get a summary with "--stat".
 +
 +<file>
 +$ git diff --stat
 + README | 2 +-
 + 1 file changed, 1 insertion(+), 1 deletion(-)
 +</file>
 +
 +When you are ready to commit to your local git repo, use git add/rm and git commit.
 +
 +<file>
 +$ git add .
 +$ git status
 +On branch bug123
 +Changes to be committed:
 +  (use "git restore --staged <file>..." to unstage)
 + modified:   README
 +
 +$ git commit
 +[bug123 7e717ac63] Update README
 + 1 file changed, 1 insertion(+), 1 deletion(-)
 +</file>
 +
 +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:
 +
 +<file>
 +To ssh://git.code.sf.net/p/rosegarden/git
 + * [new branch]          bug123 -> bug123
 +Branch 'bug123' set up to track remote branch 'bug123' from 'origin'.
 +</file>
 +
 +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.
 +
 +<file>
 +$ git status
 +On branch bug123
 +Your branch is up to date with 'origin/bug123'.
 +
 +nothing to commit, working tree clean
 +</file>
 +
 +You can list your local branches.
 +
 +<file>
 +$ git branch -v
 +* bug123    7e717ac63 Update README
 +  master    f04c831e0 cmake: Pre-compiled header comments
 +</file>
 +
 +And examine your remote branches.
 +
 +<file>
 +$ 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)
 +</file>
 +
 +==== 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:
 +
 +<file>
 +$ 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
 +</file>
 +
 +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):
 +
 +<file>
 +$ git push origin --delete bug123
 +remote: <Repository /git/p/rosegarden/git.git> refresh queued.
 +To ssh://git.code.sf.net/p/rosegarden/git
 + - [deleted]             bug123
 +</file>
 +
 +==== 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.
 +
 +<file>
 +$ git commit -am "Update README"
 +[master 556976f7d] Update README
 + 1 file changed, 1 insertion(+), 1 deletion(-)
 +</file>
 +
 +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.
 +
 +<file>
 +$ git branch -v
 +  bug222    556976f7d Update README
 +* master    556976f7d [ahead 1] Update README
 +</file>
 +
 +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:
 +
 +<file>
 +$ git branch -v
 +  bug222    556976f7d Update README
 +* master    f04c831e0 cmake: Pre-compiled header comments
 +</file>
 +
 +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.
  
  
 
 
dev/using_git.1259186654.txt.gz · Last modified: 2022/05/06 16:07 (external edit)
Recent changes RSS feed Creative Commons License Valid XHTML 1.0 Valid CSS Driven by DokuWiki