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.

No comments:

Post a Comment