Git notes

From Federal Burro of Information
Jump to navigationJump to search

Tips and Tricks

Bare repos

when making a new repo that will "receive" stuff use --bare

ssh server
user@server$ cd /data/gitroot
user@server$ git init --bare mynewproject
ssh desktop
user@desktop$ cd /home/david/work
user@desktop$ git init mynewproject
user@desktop$ touch myfile && git add myfile && git commit -m "initial import"
user@desktop$ git remote add origin ssh://user@server:/data/gitroot/mynewproject
user@desktop$ git push -u origin master

If you do not "git init --bare projectname" on the server then you might get something like this:

david@keres ~ $ git push -u origin master
Counting objects: 5, done.
Delta compression using up to 2 threads.
Compressing objects: 100% (5/5), done.
Writing objects: 100% (5/5), 1.28 KiB | 0 bytes/s, done.
Total 5 (delta 0), reused 0 (delta 0)
remote: error: refusing to update checked out branch: refs/heads/master
remote: error: By default, updating the current branch in a non-bare repository
remote: error: is denied, because it will make the index and work tree inconsistent
remote: error: with what you pushed, and will require 'git reset --hard' to match
remote: error: the work tree to HEAD.
remote: error:
remote: error: You can set 'receive.denyCurrentBranch' configuration variable to
remote: error: 'ignore' or 'warn' in the remote repository to allow pushing into
remote: error: its current branch; however, this is not recommended unless you
remote: error: arranged to update its work tree to match what you pushed in some
remote: error: other way.
remote: error:
remote: error: To squelch this message and still keep the default behaviour, set
remote: error: 'receive.denyCurrentBranch' configuration variable to 'refuse'.
To /data/gitroot/home
 ! [remote rejected] master -> master (branch is currently checked out)
error: failed to push some refs to '/data/gitroot/home'

Examine a commit before a push

git diff --cached

Visualizing changes

aka browsing changes in a terminal.

use "tig"

Error creating thumbnail: File missing

RHEL like:

yum install tig

deb. like:

apt-get install tig


also kdiff3

on mac like this:

git config --global merge.tool "kdiff3"

in .gitconfig


[merge]
        conflictstyle = diff3
        tool = kdiff3

[difftool "kdiff3"]
    path = /Applications/kdiff3.app/Contents/MacOS/kdiff3

also:

.gitconfig

[alias]
    lg = lg1
    lg1 = lg1-specific --all
    lg2 = lg2-specific --all
    lg3 = lg3-specific --all

    lg1-specific = log --graph --abbrev-commit --decorate --format=format:'%C(bold blue)%h%C(reset) - %C(bold green)(%ar)%C(reset) %C(white)%s%C(reset) %C(dim white)- %an%C(reset)%C(auto)%d%C(reset)'
    lg2-specific = log --graph --abbrev-commit --decorate --format=format:'%C(bold blue)%h%C(reset) - %C(bold cyan)%aD%C(reset) %C(bold green)(%ar)%C(reset)%C(auto)%d%C(reset)%n''          %C(white)%s%C(reset) %C(dim white)- %an%C(reset)'
    lg3-specific = log --graph --abbrev-commit --decorate --format=format:'%C(bold blue)%h%C(reset) - %C(bold cyan)%aD%C(reset) %C(bold green)(%ar)%C(reset) %C(bold cyan)(committed: %cD)%C(reset) %C(auto)%d%C(reset)%n''          %C(white)%s%C(reset)%n''          %C(dim white)- %an <%ae> %C(reset) %C(dim white)(committer: %cn <%ce>)%C(reset)'

from: https://stackoverflow.com/questions/1838873/visualizing-branch-topology-in-git

Show log

git log --name-only
git log --name-status
git log --stat

Basics

get some code:

git clone username@gitserver:/srv/gitroot/ugo-project.git

branches

list branches

git branch

make a new branch

git branch <newbranchname>

switch between branches

git checkout <branchname>
for example to switch back to master:
git checkout master

Maintenance

Backup

Clean up

taking all branches from remote and sending them to another

ensure that you have defined both source and destination remotes in your local repo.

git remote -v 
source url (fetch)
source url (push)
destination url (fetch)
destination url (push)

then do it like this:

git push destintion refs/remotes/source/*:refs/heads/*

detached head? don't lose your head.

To recover from your situation, you should create a branch that points to the commit currently pointed to by your detached HEAD:

git branch temp
git checkout temp

(these two commands can be abbreviated as git checkout -b temp)

This will reattach your HEAD to the new temp branch.

Next, you should compare the current commit (and its history) with the normal branch on which you expected to be working:

git log --graph --decorate --pretty=oneline --abbrev-commit master origin/master temp
git diff master temp
git diff origin/master temp

(You will probably want to experiment with the log options: add -p, leave off --pretty=… to see the whole log message, etc.)

If your new temp branch looks good, you may want to update (e.g.) master to point to it:

git branch -f master temp
git checkout master

(these two commands can be abbreviated as git checkout -B master temp)

You can then delete the temporary branch:

git branch -d temp

Finally, you will probably want to push the reestablished history:

git push origin master


Delete a branch here and there

first locally get out of the branch locally:

git checkout develop
Switched to branch 'develop'
Your branch is up to date with 'origin/develop'.

Now remove the local branch:

git branch -D TICKET-345-Stuff
Deleted branch TICKET-345-Stuff (was c26dbd84).

then push the delete upstream:

git push origin :TICKET-345-Stuff

Deleting your master branch

You’ve forked some project on github.

You clone your fork.

Now you’ve got a master branch. It’s the master branch of your fork.

It can be tempting to do work in the master branch and ask for a pull request.

That is best avoided because:

  • It’s natural to carry on working in your master and that will pollute your pull request with other commits
  • master is not a descriptive name for a set of changes. It’s easier for the person reviewing your code to have something like fix-for-issue-12.
  • You may well also have a tracking branch pointing to the main upstream repo. You might call that something like upstream-master. It’s easy to lose concentration and forget you are on upstream-master instead of your master, and nasty errors can result.

To avoid this, I delete the master branch from my forked copy. However, to make that work, you have to tell <a class="reference external" href="http://github.com">github</a> not to monitor your master branch.

How to delete master

First you delete master in your local clone. To do this we first make a new branch called placeholder or similar, and delete master from there:

git branch placeholder
git checkout placeholder
git branch -D master

All good so far. We next want to delete the branch on github. However, if we do this the naive way:

git push origin :master

we just get an error like this:

remote: error: refusing to delete the current branch: refs/heads/master
To git@github.com:matthew-brett/datarray.git
! [remote rejected] master (deletion of the current branch prohibited)
error: failed to push some refs to 'git@github.com:matthew-brett/datarray.git'

That is because github is looking at the master branch to provide the web content when you browse that repository. So we first have to make github look at our placeholder branch instead, then delete master.

First push up the placeholder branch:

git checkout placeholder # if not on placeholder already
git push origin placeholder

Then set placeholder to be the github default branch. Go to the main github page for your forked repository, and click on the “Admin” button.

There’s a “Default branch” dropdown list near the top of the screen. From there, select placeholder. On the interface I’m looking at, a green tick appears above the dropdown list. Now you can do (from the command line):

git push origin :master

and - no master branch...

Do I need to pull?

In a script you want to know if there have been updates upstream

1. list refs:

git show-ref


2. compare local master with remove master:

$ git rev-parse refs/heads/master
62630806fa6dd6241b4ad3a2e17602a408028948
$ git rev-parse refs/remotes/origin/master
62630806fa6dd6241b4ad3a2e17602a408028948

Same, no pull required.

now script that.

Update submodules

go to the repo that has the submodule

navigate into the submodule

git checkout master
git pull

navigate outside of the submodule

git status # see stuff
git add submodule-path
git commit -m "I updated a submodule"

My Develop won't merge into master

( maybe you should not merge ,you should rebase )

1. git checkout develop (or w/ever is your SOURCE branch)
2. git pull origin master (or w/ever is your TARGET branch)
3. git merge-tool or git checkout --ours/theirs <files-with-conflicts>, or "code ." "choose use incoming"
4. git commit
5. git push (to your SOURCE branch)
6. attempt MR again

Rebase might do you better than merge ever did

https://www.atlassian.com/git/tutorials/merging-vs-rebasing

merge rolls back to when you forked the parent, rolls the parent forward, then applied you changed to the head of the parent.



cherry picking is fun

check out the destination branch

 git checkout master

create a new branch from that:

git checkout -b TICKET#-Short-descr

cheery pick the commit where you made the messy change:

git cherry-pick b71c4a89b82154c0b239e8af16d54305047ff8ea
git mergetool

see how local working dir has changed:

git status

fix the files / search "==="

vi .gitlab-ci.yml
vi deployment/templates/scheduler/deployment.yaml.j2

add / commit

git add .gitlab-ci.yml git add deployment/templates/scheduler/deployment.yaml.j2

commit with no message:

git commit

editor opens with stuff in it already.

Git config

Setting ssh binary:

git config --global core.sshCommand "some/path"

reference: https://git-scm.com/docs/git-config ( all options )

Workflow notes

you branched of dev to get some work done.

but develop has moved on since you did this, how to "catch up"?

git pull origin develop --rebase


Your branch is ahead of 'origin/master' by X commits

Some-how you have local master branch commits that put it _ahead_ of upstream.

You want to nuke those commits and get back to the upstream master.

We assume that you don't want those commits. If you want to know what those were do it now before we nuke them from orbit.

Destroy the local branch

$ git checkout develop
Switched to branch 'develop'
$ git branch -D master
Deleted branch master (was 0fd92c3f).
$ git checkout origin/master -b master
Branch 'master' set up to track remote branch 'master' from 'origin'.
Switched to a new branch 'master'
$ git pull
Already up to date.
$ git branch
  develop
  drttestautobuild
* master

Get all remote tags

git fetch --all --tags --prune

update remote branches

git remote update origin --prune

Process: new branch, new tag push

git checkout master
git pull origin master
# make a new branch
git checkout -b drttestautobuild
git tag -a autobuild1.6.28 -m "my autobuild of v1.6.28"
# push the new tag to a remote:
git push myremote autobuild1.6.28

References