Thursday, 1 December 2016

git going

git going

What is this blog post about?

Deepening my knowledge of git (I am using 2.11.0 on Ubuntu) beyond the barely useful minimum so that

  1. I use git more in the way it was designed to be used (idiomatically)
  2. I know more clearly what the git commands I use, actually do
  3. I can use tagging effectively
  4. I can "fix things up" if something "goes wrong"
  5. I use git in a way which matches my way of thinking and working
  6. I don't use the pull command by accident

Comeback "Index" all is forgiven!

The "Index" or "Staging Area" is clearly integral to the idiomatic use of git. I wasn't able to use it initially because I didn't have enough mental bandwidth to do so. But now as I understand git a bit more it is time to bring it back into my work-flow.



These git commands in more detail

The way in which the push and the fetch commands work and their precise syntax is intimately linked to the 'local config file' that resides in the .git folder.
Here is what mine looks like (excluding the [core] entry)


[remote "github"]

        url = https://github.com/orotau/hunspell_pytest.git

        fetch = refs/heads/development:refs/remotes/github/development

        push = :



That's all there is. I have renamed the remote to "github" as it seems more clear to me than "origin" and I have only 1 branch "development".


git add -A

This will add everything. To add one file git add filename
Here is a good reference http://stackoverflow.com/questions/572549/difference-between-git-add-a-and-git-add?rq=1

git commit

Nothing to explain

git push github

The behaviour of the git push command is controlled by the push entry ":"  in the 'local config file'. Here is a description of what push does.

The special refspec : (or +: to allow non-fast-forward updates) directs Git to push "matching" branches: for every branch that exists on the local side, the remote side is updated if a branch of the same name already exists on the remote side.

git fetch github

Again the behaviour of the git fetch github command is controlled by the fetch entry "refs/heads/development:refs/remotes/github/development" in the 'local config file'.
Here is a description of what it does

When git fetch is run without specifying what branches and/or tags to fetch on the command line, e.g. git fetch origin or git fetch, remote.<repository>.fetch values are used as the refspecs—​they specify which refs to fetch and which local refs to update. The example above will fetch all branches that exist in the origin (i.e. any ref that matches the left-hand side of the value, refs/heads/*) and update the corresponding remote-tracking branches in the refs/remotes/origin/* hierarchy.

 

git merge github/development

This command merges what was in the github/development branch. Any merge conflicts will be dealt with using the meld tool (see below)


Tagging

git tag -a "tag name" will tag a commit.
My intention is to use semantic versioning as per http://semver.org/

git push github --tags will push tags up to github


Fixing things up

Undo git add

git tells you how to do this with a helpful message 'use git reset HEAD <file> to unstage'

Undo git commit

git reset --soft HEAD~ will move what is committed back to the Index.
git reset HEAD~ will move what is committed back to the Workspace.

Undo git push / git fetch / git merge

At this stage I will endeavour not to have to do these.

Fix up a Merge Conflict

A quick google search points to meld as being the tool of choice to deal with a merge conflict. The tool is easy to get to grips with and integrates well with git.

Install using the Software Centre and add an entry to the 'global config file' with git config --global merge.tool meld

git mergetool will now launch meld in the event of a merge conflict

Once you have finished using meld, then a git commit will complete the merge.

You will be left with a file with a .orig extension which can be deleted

Other Things

The 'local config file' mentioned above has a key role to play along with the 'global config file' and the 'system config file'.

Any matching entry in the 'local config file' takes precedence over the 'global config file' which takes precedence over the 'system config file'.

https://git-scm.com/book/tr/v2/Customizing-Git-Git-Configuration
is a good source of high-level information along with the more in-depth https://git-scm.com/docs/git-config.html

local config file

Edit with git config --local --edit
As above, here is what mine looks like (excluding the [core] entry)


[remote "github"]

        url = https://github.com/orotau/hunspell_pytest.git

        fetch = refs/heads/development:refs/remotes/github/development

        push = : 


global config file

Edit with git config --global --edit
Here is what mine looks like


[user]
        email = graham_oliver@yahoo.com
        name = graham-desktop
[core]
        editor = nano
[merge]
        tool = meld

system config file

Currently Empty

Disable the git pull command

I found myself reflexively issuing the command git pull rather than git fetch.
So, I needed a way to disable the git pull command.

I followed the instructions in this post
http://superuser.com/questions/276079/disable-specific-git-commands-in-a-particular-repository/276159#276159

adding this code to the end of the .bashrc file


git () {
    local disabled=$(command git config --bool disabled.$1 2>/dev/null)
    if ${disabled:-false} ; then
        echo "The $1 command is intentionally disabled" >&2
        return 1
    fi
    command git "$@"
}

and the following 2 lines to the global config file

[disabled]
        pull

This did the job and could be extended for other git commands if required.

Thursday, 19 February 2015

Git for one

Git for one | SOUL

This blog post seeks to answer these 2 questions about Git

Firstly, Git - Why bother?

Secondly, What is the absolute minimum anyone needs to know in order to make Git useful for a team of one?
It is inspired by the Mezzanine blog posts of Ross Laird and the examples will use the terminal on Ubuntu 14.04 and the web site http://github.com

Git - Why bother?

Git helps you manage the complexity of software development.
The key way it helps me is that it creates discipline.
One small change = one commit. Keeps things going slowly and steadily because if you rush and change too much code you can't usefully summarise what you have done for the commit message!

Git helps you learn as you develop and recall the learning.
Each problem you solve is recorded (providing you commit often, which I would recommend) and using github you are able to recall what you did to solve your problem, long after it has slipped from memory.

Git enables co-operation.
Once your GIT skills have improved you will be able to co-operate with others and help to produce great open-source software!

What is the absolute minimum anyone needs to know in order to make Git useful for a team of one?


# 1- Sign up for github at http://github.com

Pick a short username and a minimum length password (7 letters) because you will be typing them every time you do a commit.
sign up for github


# 2 - Install Git on your computer

Start the terminal and type in sudo apt-get update
Type in your computer password (if you are asked for it)
When this has stopped running type in sudo apt-get install git
When this has stopped running you should have installed git

# 3 - Check you can use these 5 basic commands necessary to navigate the terminal

pwd - where am I?
ls - what files and child directories are here?
cd- take me to my home directory (from anywhere)
cd .. - take me up to the parent directory
cd 'a child directory' - take me down to a child directory

# 4 - Set up Git with the basics

To get going with Git there are 3 basic bits of information you need to tell Git about. Using the Terminal again, type the following (include the ")
git config --global user.name "Your github username from # 1"
git config --global user.email "Your github email address from # 1"
git config --global core.editor "nano -w"
The final command will set Git up to use the text editor 'nano' to write your commit messages. It is simple to use and keeps you in the terminal when writing your commit messages (see below).

# 5 - Familiarise yourself with this 'Super Simple' Git workflow

A diagram that is often praised when looking at how Git works was produced by Oliver Steele.
I have taken that diagram and stripped it down to this 'Super Simple' minimum.

super simple git

The 'remote repository' will be on the github account we created in #1
The 'workspace' will be a directory of our choosing on our own computer
I think of the 'local repository' as more of a 'state' than a place

There are two basic ways to get started using Git, they are set out below. in #6 and #7.

# 6 - Get started - workspace first

From any directory, type the following command in the Terminal
git status
... leading to this response
'fatal: Not a git repository (or any of the parent directories): .git'
Despite appearances this is not at all 'fatal', it simply means that Git is asleep and needs to be woken up.

cd
mkdir git-workspace
cd git-workspace
git init
... leading to this response
Initialized empty Git repository in /home/graham/git-workspace/.git/

git status

On branch master
Initial commit
nothing to commit (create/copy files and use "git add" to track)
Git is now awake and waiting for files. So, lets create an empty file...

touch my-first-git-file.txt
git status

On branch master
Initial commit

Untracked files:
  (use "git add <file>..." to include in what will be committed)

    my-first-git-file.txt

nothing added to commit but untracked files present (use "git add" to track)
Git is suggesting we 'use "git add" to track' so let's take the advice...

git add my-first-git-file.txt
git status

On branch master
Initial commit

Changes to be committed:
  (use "git rm --cached <file>..." to unstage)

    new file:   my-first-git-file.txt
Git is showing us 'Changes to be committed', so its time to do our first commit...

git commit -a
Git starts 'nano', the text editor that we configured in #4 and you should see something like this...
nano text editor - waiting for commit message
Enter your commit message, in my case 'My first super simple commit'
Press 'Ctrl-X'
Then save your commit message by entering 'Y' and 'Enter'
[master (root-commit) bc56965] My first super simple commit
1 file changed, 0 insertions(+), 0 deletions(-)
create mode 100644 my-first-git-file.txt

The 'local repository' is now up to date and we now need to push its contents to the 'remote repository' on github.
Before we can do that we must create the remote repository on github and obtain its URL.
Go to https://github.com/new and enter the name of your repository and nothing else.
Then click 'Create Repository'
The URL of the remote repository on github is given to us at the top of the resulting page (your username will probably not be 'poopernut'!)

First connect our 'local respository' to our 'remote repository' as follows
git remote add origin "URL of the remote repository on github"

Then push the 'local repository' to the 'remote repository'
git push origin master

Enter your username and password from #1 and you are done.
Have a look at what you have created on github whilst savouring a cup of coffee!

# 7 - Get started - remote respository first

Search for a github project that you like the look of. I will use Mezzanine
From the home page of the github project you have chosen, stay calm and click on 'Fork'. (don't worry you can't do any harm!)
Now we need the URL of your remote repository which can be found here
github project URL

Go back to the Terminal and type
cd
git clone "the URL of your remote repository"

Cloning into 'mezzanine'...
remote: Counting objects: 43420, done.
remote: Total 43420 (delta 0), reused 1 (delta 0)
Receiving objects: 100% (43420/43420), 39.30 MiB | 3.07 MiB/s, done.
Resolving deltas: 100% (23782/23782), done.
Checking connectivity... done.
The Mezzanine files have arrived on your computer

cd mezzanine
git status

On branch master
Your branch is up-to-date with 'origin/master'.
nothing to commit, working directory clean
Time for another cup of coffee!