Some tips on using git

Jottings on using git to help not forget.

Some tips on using git

Better git going, if you want to start working with Open Source projects.  In case you have done a Rip Van Winkle and managed to sleep through the last 15 or maybe 2o years, CVS is dead...

Git is now the software configuration management (SCM) tool of choice for most and there are huge git repositories at GitHub and GitLab amoungst others.

This is not a definitive guide git, which is well documented at git-scm.com, these are just my git helper notes so I can stop having to go to the web to remember how to do something or look at my command history to recall how I got to where I needed to be.

This is not advanced git! You can do an awful lot of useful things with a relatively small set of core git knowledge.


The git model:

  • There is no master repository, all repositories are equal
  • There is however a local repository and remote repositories
  • The local repository is likely where you are doing your work (changing code, compiling, fixing things etc),
  • While the remote respositories are places where you send stuff to because its done or you where draw down on stuff to add to what you are working on
  • Your local respository can draw on any number of remote repositories and
  • Your local and remote repositories can contain branches and tags.
  • Within your local repository you will be actively working on a single branch
  • The number of repositories you are drawing on while you work is limited by your memory and
  • There is a common naming convention which has "upstream" as a main central repository that is contributed to by many parties and if you start work by cloning an existing repository, then this remote repository you clone from will be identified as "origin".

So off we go...


Starting by cloning an existing repository

This is the simple ...

# git clone https://github.com/zebity/pkg-debian.git

To clone a project will all branch and tag information and then push to new repostitory:

$ git clone --bare http://FROM.DOM/EXISTING.git
$ cd EXISTING
git push --mirror http://TO.DOM/NEW.git

Putting your new project up on github

To start a new project on github has a few quirks..

Here is summary of steps:

  1. Create new repository in github - selecting .ignore, license and other standard items if you want them
  2. Clone the new "empty" repository down to your local workstation
  3. [Optionally - if you want to base this project on existing one then, add new remote respository" "git remote add NAME REPO-DETAILS"
  4. [Optionally - fetch and pull code from repo: "git fetch -tags NAME BRANCH" & "git pull -tags [--allow-unrelated-histories] NAME BRANCH"]
  5. Add your files and stuff
  6. Commit back to github repo: "git commit -am "add new and old files" & "git push --tags"  

7. All done

NOTE: This repeats some of what is also covered below


Realigning your local repository with a remote one, including "upstream"

Before merging with an remote repository, you need to consider.

  1. What branch in my local repository tree so I want to merge the remote code into
  2. What is the remote respository that I want merge from

So to see what branches you have in your local repository and check which one you are on do, and swap branches if you are not on the right one:

# git branch
  master
* split-main
#
# -- the one with asterix is the branch you are one
# -- now if you want to swap branch then do a checkout
#
# git checkout master
Switched to branch 'master'
Your branch is up to date with 'origin/master'.
#
# -- note that if you have uncommited changes within the branch,
# -- then the checkout will fail

Now lets get the juicy code from our remote repository.

# -- first let see what remote repositories we have
# git remote -v
origin	https://gitlab.com/zebity/commento.git (fetch)
origin	https://gitlab.com/zebity/commento.git (push)
other	https://gitlab.com/matclab/commento.git (fetch)
other	https://gitlab.com/matclab/commento.git (push)
upstream	https://gitlab.com/commento/commento.git (fetch)
upstream	https://gitlab.com/commento/commento.git (push)
# -- so you can see that we have 3 remotes: origin, other and upstream
# -- be aware that asides from origin, these names are arbitrary

Optionally if you are not connected to the remote repository you want to pull code from then add this remote repostiry:

# git remote add nirvana https://github.com/nirvana/commento.git

Ok now lets merge the code and push the results back up to my remote origin repository:

# git fetch nirvana master
remote: Enumerating objects: 63, done.
remote: Counting objects: 100% (63/63), done.
remote: Compressing objects: 100% (8/8), done.
remote: Total 84 (delta 57), reused 55 (delta 55), pack-reused 21
Unpacking objects: 100% (84/84), done.
From https://github.com/nirvana/commento
 * branch              master     -> FETCH_HEAD
   b5b5d43f..a146d756  master     -> upstream/master
#
# -- now we have code do the pull / merge
#
# git pull nirvana master
From https://github.com/nirvana/commento
 * branch              master     -> FETCH_HEAD
Updating 1137e9e5..a146d756
Fast-forward
 Makefile.am           |  8 ++++++--
 configure.ac          |  7 ++++---
 src/collectd-snmp.pod |  4 ++++
 src/collectd.conf.in  | 10 ++++++++++
 src/exec.c            |  5 +++++
 src/network.c         |  9 +++++++++
 src/snmp.c            | 36 +++++++++++++++++++++++++++++++++---
 7 files changed, 71 insertions(+), 8 deletions(-)
 #
 # -- ok no conflicts! So lets push the result up to my personal remote
 # git commit -am "Remerge with grand master at nirvana"
 # git push
 #
 # -- all done

NOTE 1: In this example I have used the name "nirvana" as my upstream remote. This just to emphasize that the name is arbitrary and that the "upstream" remote is just named as such by convention.

NOTE 2: Those with eye for detail will also see that I have mixed my local repository with code from both gitlab and github repositories. Again git is transparent to these organisational constructs.

NOTE 3: Yes I have mixed up commento and collectd stuff in this example, because it is only an example


Remove a Commit/s

Removing a git commit can be very easy or very hard depending where the commit is  in history.

The most simple if pop'ing last set of commits and more complex is to to find commit and wind out and manage potential impacts.

  • "git-log" - to get commit log
  • "git reset HEAD^" - pop last commit:
  • "git revert <COMMIT-ID>" -  achieve the same as "reset HEAD", where <COMMIT-ID> can be found from git log

For more complicated needs the repeatable process to remove the commits and have result be merged into a new branch. This can then be remerged back into master branch.


Merging Branch with Master

If you have been working with a branch and now wish to re-align it with master  (but not commit back to master) the you need to:

  1. Verify which branch you want to work with: "git branch -v -a"
  2. First do checkout of the branch what you wish to merge: "git checkout BRANCH"
  3. Merge with master: "git merge master"
  4. [Address any conflicts resulting from merge]
  5. Commit into the merged branch: "git commit -am "COMMENT""
  6. Now if you want you should be able to push the branch back up to master: "git push"

Using branches within your local repository to maintain seperation from other remote repository work


Contributing to Open Source projects with Pull / Merge requests


Links & References:

Git - the second invention of Linus of Linux fame and incredibly useful and powerful SCM