- 1 Ignore File Mode
- 2 Working on a remote terminal
- 3 Tracking remote branches
- 4 Tracing in Status
- 5 Just the facts
- 6 What is this miscellaneous file, and how does it compare to what's in my repo?
- 7 Compare a file between branches
- 8 Add that forgotten file
- 9 Git Branch
- 10 Comparing Branches
- 11 Don't merge, Rebase!
- 12 Delete local and remote merged branches
- 13 Git Log
- 14 Tags
- 15 Git merge branch of another remote
- 16 Unbloat
- 17 Put your project on GitHub
- 18 Create a README from a webpage
- 19 References
Ignore File Mode
Sometimes you have to temporarily change file modes (or some script might alter your working directory). Anyway, to ignore file mode changes temporarily, you can just add
-c core.fileMode=false to your command. E.g.:
git -c core.fileMode=false status
You can also put this into a repo or global config, but you probably shouldn't.
If you need to change filemodes back to the way they were in the repo, you can do something like
git diff --summary | grep --color 'mode change 100755 => 100644' | cut -d' ' -f7 | xargs chmod +x git diff --summary | grep --color 'mode change 100644 => 100755' | cut -d' ' -f7 | xargs chmod -x
Working on a remote terminal
If you're working on a remote terminal and your repository get's complicated, but you don't have desktop tools like meld or gitk to look at it, you can copy the remote repo to your desktop with
rsync, even if you have to jump through a bastion host with something like:
rsync -e "ssh -t bastion ssh -A" -ravz firstname.lastname@example.org:/opt/meza/ ./meza-es1/
If that complains about host-key verification, then simply do an SSH first to the host, accept the host key identity, and logout. Now the rsync will work because the host-key is already accepted as valid.
Tracking remote branches
Checkout a specific branch from origin, and track it.
What if you enter
git checkout -b REL1_29 when you *should have entered*
git checkout -b REL1_29 origin/REL1_29? J
ust tell git that you meant to track the branch in origin: Set upstream doesn't do what's intended here! You should delete the branch that you created as a 'copy'; and then checkout the branch correctly. To checkout the branch correctly, just IGNORE the
git branch --set-upstream-to=origin/REL1_29 REL1_29
-b flag altogether. If you do use the
-b flag, then you must use the long form that references the remote branch to track. If you just do a '
git checkout foo' and there exists the same branch upstream at
origin/foo then git will checkout a new branch set to track the remote.
Tracing in Status
GIT_TRACE=1 to your command to see more of what's going on. (Note that there are no spaces and no semicolon.)
GIT_TRACE=1 git status
Just the facts
Want simple red/green diff lines?
See all the changes in color, but without any context lines, and without the leading +/-/[space] This makes it easy to grab changes and stuff them in another file for example.
git diff -U0 --color myfile | sed -r "s/^([^-+ ]*)[-+ ]/\\1/"
What is this miscellaneous file, and how does it compare to what's in my repo?
Say you've got a config file lying around (untracked) in your local working tree. It's not in your current project branch, but you know it's an important file. How does it compare to what's in the freephile remote, es128 branch version of the file?
git diff freephile/es128:config/core/MezaLocalExtensions.yml config/core/MezaLocalExtensions.yml
Compare a file between branches
Do you think a particular file has changed between two separate feature branches (ea based off master)?
# git diff branch1..branch2 -- path/to/file git diff es128-rebased..get-to-know-meza -- manual/commands.md
Add that forgotten file
You forgot to add a file to the last commit? Just add it to the index, and commit with
--amend. Added a file that shouldn't be there?
git rm it. If you leave off the -m (message) option in the new commit, it will let you re-use the last commit message. This lets you "undo the last commit" and redo it right. You usually do not want to amend a commit if you've already pushed it to other repos, but if it's just local
--amend is awesome-sauce.
git add forgotten.php git rm oops.txt git commit --amend git log --stat
- list the branches you have locally
git branch --list
- list the branches that are on remotes
git branch -r --list
- checkout a remote branch, setting the local one to track
git checkout -t freephile/patch-1
- git branch --merged (while on master) shows you branches which are fully contained in HEAD, and can be deleted.
What's in this old branch, not in my new branch (ignoring merges)?
- git log oldbranch ^newbranch --no-merges
- git log master..feature (everything on the feature branch that is not in master)
- git log origin/master..HEAD (everything in the local branch that you would push)
- git log --left-right master...experiment (triple dot shows everything since the common ancestor) 
Don't merge, Rebase!
Get familiar with how to rebase your work each day http://www.bitsnbites.eu/a-tidy-linear-git-history/
Delete local and remote merged branches
git branch --merged | egrep -v "(^\*|master|dev)" | xargs -I % echo 'git branch -d % ; git push --delete freephile % ;'
Using echo helps you look before you leap. % is the replacement string in
xargs. Change '
echo' to '
sh -c' to execute. Does both local and remote prunes.
--stat gives a nice view of what happened in the log.
git log --stat # try these other git log variatiations git log --patch git log -2 git log -p -2 # - p is the same as --patch git log --pretty git log --pretty=oneline git log --pretty=short git log --pretty=full git log --pretty=fuller git log --graph git log --pretty=oneline --graph git log --name-only git log --name-status git log --abbrev-commit git log -S<string> # find when the number of instances of the string are added or deleted git log -G<regex> # same with POSIX extended regex git log -- filename # look for commits that touch filename git log -p -- filename git log --since 'last week' git log --since 2017-01-01
How do you ignore a directory, but make an exception? What if you already added certain directories to git but want to stop tracking them now (ie. "take them out of version control")?
A combination of editting your
.gitignore file and
git rm --cached to the rescue. I had accidentally added and committed some files into git which should have been ignored because they are 3rd party files managed by Composer. I fixed my
.gitignore to track only what I want while ignoring a parent directory:
/nbproject/* # ignore everything in the 'vendor' directory /vendor/* # but don't ignore the 'eqt' directory !/vendor/eqt/
Then you simply remove all files from git's index, and add them back (only now adding them back will look to .gitignore for the corrected rules)
git rm -r --cached . git add . git commit -m 'ignoring vendor/*'
With git, you can just tag something with
git tag foo. This produces a 'lightweight' tag . Use "annotated tags" whenever you want to know when something was tagged and who did it. Pass an empty message if you really don't care or need extra annotation.
git tag -am '' 'REL-1.0-alpha'
When using git between a local repository and a single 'origin' remote, it's a simple process to work locally and push things back up to origin. But, what if you have a separate remote repository... perhaps on GitHub, or a collaborator who has similar sources but not using your origin (so disconnected, and perhaps not even linked ancestrally like a fork). How do you add that other remote to your project and then pull in the code "they" have on top of yours? Here's an example of how we started with a repo from github and added a repo that we were developing privately. (The reality is that we were developing a repo privately; created a sibling version of the code at github; and then wanted to re-incorporate the changes of the github repo back into our private repo.)
# start with one 'origin' remote git clone https://github.com/freephile/qb.git # add another remote that has similar code git remote add private greg@eqt:/home/greg/src/ad.git # check git remote -v # rename it for the host it came from git remote rename private eqt # pull our 'eqt' remote onto the master branch of the code we got from 'origin' git pull eqt master # But there are some unversioned files in the way (git complains) # So, create a new 'dev' branch and stuff all the new things there (which we can either delete, or resume later) git checkout -b dev git add hosts package.json requirements.txt scripts/ git commit -m 'stashing some files into a dev branch' git checkout master # now we can merge again git pull eqt master # git complains about some merge conflicts (changes on both sides so it can't just do a fast-forward) # edit those files to remove the conflict markers and get them the way you want them git add install* launch.yml # finish your merge by committing the result git commit -m 'merged additional plays from eqt' # and push upstream to 'origin' git push # and push to other remote 'eqt' git push eqt
git -c gc.reflogExpire=0 -c gc.reflogExpireUnreachable=0 \ -c gc.rerereresolved=0 -c gc.rerereunresolved=0 \ -c gc.pruneExpire=now gc
Put your project on GitHub
Been hacking away on a project and now it's time to unveil it? Here are the quick and easy steps to get your local repo into your GitHub account.
# first make a "bare" clone # from your server git clone --bare email@example.com:/var/www/baz.com/www/project # or from a local directory git clone --bare /tmp/project # produces project.git directory cd project.git # push that to your new project (created via browser at GitHub.com) git push --mirror https://github.com/USER/project.git # go back to the original project folder cd /tmp/project # optionally remove local remotes that are no longer needed git remote remove origin # add GitHub as a remote named 'github' (assuming SSH key-based auth) git remote add github firstname.lastname@example.org:USER/project.git # pull in anything from 'upstream' (assuming that now GitHub is the canonical source) git pull github master # push any changes up; setting the new remote as the upstream for the 'master' branch git push --set-upstream github master # from now on you can just 'git push' from master
Create a README from a webpage
pandoc --standalone --read html https://freephile.org/barcode/index.html -o README.md