john pfeiffer
  • Home
  • Categories
  • Tags
  • Archives

Git branch diff server init stash undo uncommit ssh config forward agent

[TOC]

Stash and Reset

Before git pull it is probably smart to stash (hide and protect) your local changes.
Or conversely you may need to undo a commit you have made locally (the changes remain in the filesystem but are not recorded in git)...

git reset --soft HEAD^

remove a single commit before it was pushed, the brute force way of not having to use git rebase to quickly fix something before git push

git stash

hide your local changes (this will ignore new files which might still collide after a git pull (shrug)) this has the useful side effect of undoing "git add"

git stash list
    stash@{0}: WIP on master: 9fb7df8 parent commit message here

list the number of cached local changes in the stack

git stash pop

pop off the local stack the most recent cached local changes this may create conflicts that must be resolved - and after resolving the changes you may have to git stash drop

git stash drop
    Dropped refs/stash@{0} (95915fd57ff7734c370e8587ca1e97457c013043)

delete a cached local change (be careful!)

Branches

Create a new branch

git branch NAME
git checkout NAME
git add --all .
git commit -m "JIRA number"
git push --set-upstream origin NAME

sometimes it is faster to type git push and copy paste the error message with the branch name (badpokerface)

Some older notes :

git remote add new-branch-name git://user@bitbucket.org/user/myproject.git
touch .gitignore
git commit -a -m "added an empty .gitignore"
git push --set-upstream origin new-branch-name

git status

On branch new-branch-name, othing to commit, working directory clean

Create a git branch from a previous commit

git branch NAME <commitsha>
git checkout NAME

this creates the new local branch starting with the commit, the second command actually uses the new local branch

Merge master into your branch

Merging is the big reason to use distributed version control. Changes from different "parents" can be "auto-merged" and the end result is more productivity.

A few things to remember:

  1. Never rebase a branch that someone else is using (since rewriting history essentially forces everyone to git clone again and try and re-apply their changes by hand)
  2. master is just a branch name
  3. auto merge is just software trying its best, you should always double check the result (i.e. sometimes extra lines can be added which in dynamic languages won't even cause data corruption or crashes until runtime)
  4. merge master into your branch first to minimize the conflicts
  5. git pull is really git fetch and git merge in one step, so git fetch provides more control over how the merge occurs

    git checkout master git pull git checkout new-branch-name git pull git merge master Merge branch 'master' into new-branch-name # preserves all commit history and messages

    git push # push master + new-branch into new-branch repo on remote Counting objects: 1, done. Delta compression using up to 24 threads. Compressing objects: 100% (3/3), done. Writing objects: 100% (3/3), 362 bytes | 0 bytes/s, done. Total 3 (delta 2), reused 0 (delta 0) To git@bitbucket.org:username/myproject.git 008d6c4..e2cbf40 new-branch-name -> new-branch-name

    git branch -v master 26572a7 add some random feature * new-branch-name e2cbf40 Merge branch 'master' into new-branch-name

    git clone user@repository.domain.com:projectname.git # --recursive? git remote show origin (discover the url, name, and branches)

    (or git remote -v)

    git pull; git submodule update --init --recursive; # update including submodules

Delete a branch

git push origin --delete <branchName>

Deleted a remote branch

git branch -D <branchName>

Deleted the local branch

Remove Changes and Cherry Pick Commits

Remove changes before a push

git rm --cached mylogfile.log       # remove a single file from git repo (without deleting the local copy)
git rm -r --cached .idea        # remove folder with pycharm project files from git repo without deleting the local copy

# removing from git stuff that's already been deleted on the LOCAL system
git add -u   # update
git rm $(git ls-files --deleted)    # OR this alternative


git push = "! [rejected]        master -> master (fetch first)"         # push failed so now fixing it...

git status                      # we have a commit saved
git log                         # view commits history

git reset --soft HEAD^          # keep the index around just in case
git status                      # see we've "uncommitted"
git stash                       # save local changes
git status                      # verify master clean

git pull                        # get the new stuff
git log                         # verify the new stuff

git stash pop                   # retrieve local changes
git add .                       # add local changes (preparing a commit)
git commit -m                   # commit message
git push                        # finally!

git tag -a 1.3.2 -m "product version 1.3.2 release"
git push --tags

git tag -a 1.3.2 1fd2f84fbfafc5fa998bfbb4f776058f116062f1 -m "product version 1.3.2 release"

to pin the tag to a specific commit (i.e. not HEAD)

git tag -d 1.0
git push origin :refs/tags/1.0

Delete a tag


Git Cherry Pick a specific commit

git cherry-pick afd3be516abf90e3d22c26fa01a560ae70510247

use a commit from a branch to merge into master

git reset --merge

abort a cherry pick (i.e. too much manual conflict resolution required)


squashing commits locally is safe squashing commits after pushing to remote is DANGEROUS since it involves rebase IF anyone else has pulled (which in a large enough team definitely happens) - master is just a branch so two people on the same branch = no rebase!

git log

commit afd3be516abf90e3d22c26fa01a560ae70510247
Author: John Pfeiffer <user@example.com>
Date:   Thu Aug 29 09:22:46 2013 -0700
remove the old commented line

commit 08b93ed3ccc6496fd0e2bc0ce0fbff8c637cb72b
Author: John Pfeiffer <user@example.com>
Date:   Thu Aug 29 09:16:19 2013 -0700
modify name to more descriptive cdn_prefix

commit 766674af64c41d72a4430b228802d0c45e20f0bf
Author: John Pfeiffer <user@example.com>
Date:   Thu Aug 29 09:14:28 2013 -0700
add https prefix to cdn config



git rebase -i HEAD~3

CHANGE FROM pick pick pick

TO pick squash squash

:x  (save and exit)

This is a combination of 3 commits. The first commit's message is:

add https prefix to cdn config, modify variable name to more descriptive cdn_prefix, remove the old commented line

git log    # verify the new squashed commit

git push -f             # force the push , similar to git push origin +master

Git Logs and Stats

git help
git status


git whatchanged --all --committer="pfeiffer@"

list all entries by a specific string in committer https://git-scm.com/docs/git-log

git shortlog -s -n

a sorted list of the number of commits by each "author" (so if you commit with different names it will be split) https://git-scm.com/docs/git-shortlog

git log --author="John"
git log --after="2014-7-1" --before="2014-7-4"

git log -p -2

diff of the last two commits

git log --stat

commit history (reverse chronological order)

git show <hash of some commit>

e.g. de3513f4f740934d0a97da8c97a58b35968b03ac , this will show you the actual diff

git log -- filename.txt

see the history for a single file

git log --pretty=oneline                # shows commits on one line each
git log --pretty=format:"%h - %an, %ar : %s"

git reflog      # shows when tip of branches are updated

https://www.atlassian.com/git/tutorials/git-log/filtering-the-commit-history

gitk                    # GUI for git commit history


git blame setup_s3.sh           # shows the last commit each line was modified, e.g. 6d4134f4...
git blame -L8,+3 "6d4134f4^" -- setup_s3.sh # check Line 8 (the 3 lines around it) but starting FROM 6d4134f4...

continue until you've tracked it down

git whatchanged --stat  # slightly different way of viewing most recent commits
git whatchanged since until -- filename.txt

git diff new-branch-name    # all of the changes
git diff --name-status new-branch-name   #just the file names
M       folder/filename.py

git diff new-branch-name  folder/filename.py   # just the one file

GIT_PAGER='' git diff

allows line wrapping

git diff Example.java

shows the changes between the local file and the committed repo file

git blame Example.java

shows who last modified each line of code (not including deletions)

git add *.java
git commit -m "initialize repo"
git status

git ls-files 
git ls-files  file_name --error-unmatch
git ls-files | wc -l
git ls-tree -r --name-only HEAD
git ls-tree -r --name-only MASTER | wc -l

Merge a repository into another and maintain file history

git clone A
git clone B

cd A
git config --list
cd ../B
git config --list

git remote add git@bitbucket.org:USERNAME/A.git
git config --list
git fetch A
git merge A/master  # or whichever branch you prefer
git remote remove A

Import a history from one repo to another

git remote add other /path/to/XXX
git fetch other
git checkout -b ZZZ other/master

mkdir ZZZ
git mv stuff ZZZ/stuff             # as necessary
git commit -m "Moved stuff to ZZZ"

git checkout master                
git merge ZZZ                      # should add ZZZ/ to master
git commit -m "merging in other repo history"
git push

git branch -D ZZZ                  # to get rid of the extra branch before pushing

Forking a subset of a repository

REMOVE ANY REFERENCE TO THE ORIGINAL REMOTE REPOSITORY SERVER

git config --list
git remote rm origin

REMOVE ALL TAGS (because often they are abused and useless)

git tag | xargs git tag -d

KEEP ONLY N DIRECTORIES FROM AN EXISTING REPO

git filter-branch --index-filter 'git rm --cached -qr -- . && git reset -q $GIT_COMMIT -- first/directory second/directroy' --prune-empty -- --all

CLEAN UP ALL OLD ARTIFACTS FROM GIT HISTORY

git reset --hard
git for-each-ref --format="%(refname)" refs/original/ | xargs -n 1 git update-ref -d
git reflog expire --expire=now --all
git gc --aggressive --prune=now

CONFIGURE THE PRUNED/REFACTORED REPOSITORY TO BE A NEW REMOTE REPOSITORY

git remote add origin git@bitbucket.org:myproject/myreponame.git
git config --list

SEND YOUR NEW

git push --set-upstream origin master


Install Git on Ubuntu

sudo apt-get install git-core
which git

/usr/bin/git

git --version

Git from source

wget http://kernel.org/pub/software/scm/git/git-1.7.2.3.tar.gz
tar -xvf git-1.7.2.3.tar.gz
cd git-1.7.2.3/
sudo apt-get install libcurl4-gnutls-dev libexpat1-dev gettext libz-dev libssl-dev
make prefix=/usr/local all
sudo make prefix=/usr/local install

which git

/usr/local/bin/git

Git from git

git clone git://git.kernel.org/pub/scm/git/git.git      #   GIT FROM GIT
cd git
git tag
v1.7.2.3
v1.7.3-rc0
v1.7.3-rc1
v1.7.3-rc2
git checkout v1.7.3-rc2
make prefix=/usr/local all
sudo make prefix=/usr/local install
which git

/usr/local/bin/git


SETUP GIT ON A LOCAL MACHINE

sudo apt-get install git  
git config --global color.ui true
git config --global user.name "John Pfeiffer"
git config --global user.email "jpfeiffer@example.com"
git config --list

git config user.email "another@example.com"

a config, i.e. email, can be set per repository too

git config user.email

another@example.com displays the current configuration

git config -e

edit the config file (same as vi .git/config)

ssh -T git@bitbucket.org # verify git can connect with an ssh key, if not make sure it is created and

ssh-keygen -f ~/.ssh/identity_name -C "identity_name"  # creates identity_name and identity_name.pub (the second is for github/bitbucket)
# your fingerprint is: ...
# The key's randomart image is:
# +--[ RSA 2048]----+


vi /home/ubuntu/.ssh/config         # Port allows for a non standard port

Host remoteserver.net
  HostName remoteserver.net
      PreferredAuthentications publickey    # this will prompt the first time to add the remote host
      Port 22
  User git
  IdentityFile ~/.ssh/github_rsa

# ensure the key is added with ssh-add -l  (should display 2048 8a:1a:ac:6... identity_name (RSA) )
# when connecting troubleshoot using ssh -vT git@github.com  (or ssh -vT username@bitbucket.org)

~/.ssh is where you keep your ssh keys

ssh-add -l

list what the ssh agent knows about

ssh-add -D

delete all the current identities

vi ~/.ssh/config
  IdentityFile ~/.ssh/id_rsa
  Host my.example.com
  ForwardAgent yes

do not forward your agent to everyone as every server you log into might be able to leverage your session while you're logged in

ssh-add ~/.ssh/id_rsa

vi ~/.ssh/config

# ensure ~/.ssh/config contains the following, allows the target server (jumpbox) to re-use ssh-agent (/bin/sh ssh-add)
IdentityFile ~/.ssh/id_rsa


Host first.gitserver.com
  HostName first.gitserver.com
  User git
  IdentityFile ~/.ssh/id_rsa_privateserve
      ForwardAgent yes

Host github.com-personal
  HostName github.com
  User git
  IdentityFile ~/.ssh/github_rsa


git clone git@bitbucket.org:username/reponame

requires ssh-agent, ssh-add and your ssh keys all correctly configured

git clone https://username@bitbucket.org/username/reponame.git

prompted for username and password unless it's a public repo


FIX GIT PROMPTING FOR PASSWORD (USE SSH INSTEAD OF HTTPS)

git config -l # list the configs, note:

remote.origin.url=https://foupfeiffer@bitbucket.org/foupfeiffer/xmpp.git

CHANGE PROTOCOL

git config --unset remote.origin.url git config --add remote.origin.url git@bitbucket.org:foupfeiffer/xmpp.git

git config --add remote.origin.url https://foupfeiffer@bitbucket.org/foupfeiffer/xmpp.git

ps -e | grep [s]sh-agent # if ssh-agent is not running: ssh-agent /bin/bash ssh-add -l # list the keys the agent is managing ssh-add ~/.ssh/id_rsa # may be password prompted

to ensure it's permanently added, vi ~/.ssh/config IdentityFile ~/.ssh/id_rsa

note that /etc/ssh/ssh_config would apply to all users on the system

make sure the ~/.ssh/id_rsa.pub key has been added to your remote repo (bitbucket)

Lubuntu and LXDE: vi /etc/xdg/autostart/gnome-keyring-pkcs11.desktop

Exec=/usr/bin/gnome-keyring-daemon --start --components=pkcs11 OnlyShowIn=GNOME;Unity;MATE;LXDE;XFCE;

vi /etc/xdg/autostart/gnome-keyring-ssh.desktop

Exec=/usr/bin/gnome-keyring-daemon --start --components=ssh OnlyShowIn=GNOME;Unity;MATE;LXDE;XFCE;

cd /home/ubuntu/myproject (download a base .gitignore for your language from github) git init git add .gitignore git commit -m "initial .gitignore" git remote add origin git@remoteserver.net:/home/git/GITREPOS/project.git git push origin master # Perhaps you should specify a branch such as 'master'

    Counting objects: 3, done.
    Delta compression using up to 4 threads.
    Compressing objects: 100% (2/2), done.
    Writing objects: 100% (3/3), 581 bytes, done.
    Total 3 (delta 0), reused 0 (delta 0)

to fix error beginning: "You asked me to pull without telling me which branch you want to merge with, and 'branch.master.merge'"

git branch --set-upstream master origin/master

git pull --rebase # apparently rebase is cleaner than merge (which is pull's default) EXCEPT if someone depends on those commits

optionally investigate with

git remote show origin git remote -v

every commit is identified by a SHA (40 characters)



clone only a branch

git clone -b mybranch --single-branch git://user@bitbucket.org/user/myproject.git vi somefile git commit -a -m "somefile" git push origin mybranch # you MUST indicate what branch to update

probably better to just use git checkout or track but...

git pull git branch git checkout mybranch # Already on 'mybranch'

CLONE THE WHOLE REPO AND THEN SET IT TO A SPECIFIC COMMIT, DELETING A BRANCH, CREATING A NEW BRANCH

git clone https://user@bitbucket.org/project

git reset --hard 93b149c0bb0800e81467028f170a99adac587c82       ( a specific commit against master)


.gititgnore SAMPLES

!.java # The easy way (just java files)


The hard way... at the root of the git repo create a text file .gitignore

*.class

Package Files

.jar .war *.ear

maven build artifacts

target/

/target/


THE BEST WAY TO MERGE (when git pull gives you the unfortunate news...)

Updating 7052d46..9c531c7 error: Your local changes to the following files would be overwritten by merge: project/src/main/java/com/Example.java

Please, commit your changes or stash them before you can merge. Aborting

git stash # now your current local stuff is saved git pull # now your local repo reflects the remote git stash pop # auto merge your changes back into your local repo

Now look for any errors where a merge must be fixed/handled manually


to remove previous mistakes

git rm *.class -f

forces the removal, then do a git commit and push

OR

git stash
git reset --hard HEAD

REMOVING LOCAL COPIES BEFORE DOING A GIT PULL

1) git checkout -- .

checkout the latest version and overwrite old files not affect deleted, renamed, or new files

2a) git stash save --keep-index 2b) git stash drop

stash uncommitted files, then drops them entirely. Good if there are committed changes to keep and uncommitted/unstaged changes to discard

3)git reset --hard

Wipes out everything since the last commit, including file renames, deletions, and additions

4) git clean ?


git mv is merely a convenience method. git does not "track" renames (that is, it can detect them, but they are not recorded as an operation like an add or remove)

instead just use "git add" and "git rm" (and git log --follow if you want to see history)


CREATE, INITIALIZE, AND PUSH TO ORIGIN MASTER A NEW REPO

mkdir /workspace/TEMP (master) cd /workspace/TEMP git init touch empty-file-initialize-repo.txt git add empty-file-initialize-repo.txt git commit -m "empty-file-initialize-repo" [master (root-commit) 0df7d96] starting the repo 0 files changed create mode 100644 temp.txt

git remote add origin git@server.com:projectname-common.git git push origin master Initialized empty Git repository in /ebs/data/gitosis/projectname-common.git/ Counting objects: 3, done. Writing objects: 100% (3/3), 224 bytes, done. Total 3 (delta 0), reused 0 (delta 0) To git@server.com:projectname-common.git * [new branch] master -> master

//NOW THE "MAIN" server has the new repo

cd /workspace

git clone git@server.com:projectname-common.git Cloning into 'projectname-common'... Receiving objects: 100% (3/3), done. remote: Counting objects: 3, done. remote: Total 3 (delta 0), reused 0 (delta 0)

//CLEANUP THE TEMPORARY BOOTSTRAP REPO rm -rf /workspace/TEMP


SETUP GIT: REMOTE SERVER ssh ubuntu@remoteserver.net

apt-get update apt-get install git-core

sudo adduser git su git cd ~ mkdir .ssh

mkdir -p /home/ubuntu/.ssh/

vi /home/ubuntu/.ssh/authorized_keys

cat /tmp/id_rsa.john.pub >> ~/.ssh/authorized_keys cat /tmp/id_rsa.john_github.pub >> ~/.ssh/authorized_keys

ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAtl0zMQSXCVUg4kNZV3LtlyLBaUg9fTtDybzq3YTYxuzR4ZO+JlAFj1bLobdh2/6zgfe5cd9mDdWCAJXif7aaYRHqUBej4TTbdvWoCednjhaB4V06ddkof+3SuZKDt5/lYNAcEidzj+sLkEmDsaH126AZIe93btYq/lraDxfdlUr3m1Q2WaqzNeoPmvZW8o/VdrYlR8hWEETZ4Bg+8ZSpuqKO7nWU1q82w== John@HPDV7

chown git:git ~/.ssh/authorized_keys chmod 600 ~/.ssh/authorized_keys

cd /opt/git mkdir project.git cd project.git git --bare init

MORE INFO: git-shell to restrict users shell access


PREREQUISITE

Window -> Preferences -> General -> Network Connections -> SSH2

Key Management (tab) -> Generate RSA Key

"You can paste this public key into the remote authorized_keys file"

ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAAgQCBOKhzHKQMdxZxf5d4qpazvt/CGxERmRain0c7rLJBYI4wcVk0nUpKFH/d3Tj9L1f+CjsScHXBK9LI77YAlYOVX9gfEZskwEdJats1Cup7VN4NLbzlxP0gGB9HTf1B+ZKC8VRG+Z8DxAok70IESpWV9RKLehHlpQsEieitq7zyaw== RSA-1024

Save Private Key! (e.g. becomes ~/.ssh/id_rsa and ~/.ssh/id_rsa.pub)


GIT REPO SIZE MANAGEMENT

git verify-pack -v .git/objects/pack/pack-*.idx | sort -k 3 -n | tail -5

git rev-list --objects --all | grep

UNFORTUNATELY permanently removing commits (and then the objects) from the history (and pack) is very difficult




Submodules: http://git-scm.com/book/en/Git-Tools-Submodules

after a clone (recursive) the submodule will appear under a directory submodules, also at the top level there will be .gitmodules

git clone --recursive git@bitbucket.org:myuser/myproject.git

if there is a change upstream to the submodule git status will show "changes not staged for commit"

cd myrepo

git pull

cd myrepo/submodule/foo

git pull

cd myrepo

git submodule update Submodule path 'submodules/myupstreamproject': checked out '84518ee287ee1eb1a40210d339665a85a02461e6'

after a "git pull" on the main repo you must also run a "git submodule update" (to get changes made to the submodule upstream)

IF you have a branch you have to do the same thing twice (once on master and once on the branch) SO AVOID having multiple branches in a submodule

IF you have accidentally modified your submodule directly it's highly recommended to "git checkout -- submodule" (i.e. use a two lane road, modify your upstream projects directly and just use git submodule update to pull down new changes)

IF you're unable to see the changes to submodule:

cd myrepo/symlink-to-submodule-subdir git branch git checkout master git pull cd myrepo git submodule update

now check again if it's still not there repeat via cd myrepo/submodule/submodulename


  • « Amazon aws cli
  • cherokee redirect »

Published

Dec 4, 2015

Category

linux

~2852 words

Tags

  • branch 1
  • cherry pick 1
  • config 3
  • diff 4
  • git 8
  • git branch 1
  • git log 1
  • init 4
  • linux 249
  • server 66
  • ssh 14
  • ssh agent 1
  • ssh forward 1
  • stash 1
  • uncommit 1
  • undo 1