Monday, June 30, 2014

How a Makefile Works

Make is a utility that automatically builds executable programs and libraries from source code by reading files called makefiles which specify how to derive the target program.

Besides building programs, Make can be used to manage any project where some files must be updated automatically from others whenever the others change.

The example below shows how to use a Makefile to automatically compile a C source code file "example.c" (only when it has been changed) and then execute the compiled file "./example".

./example.c

Create the source file.

#include
int main()
{
 printf ("Hello\n");
 return 0;
}


./Makefile

Create the Makefile.

exec: compile
 ./example

compile: \
example.c
 gcc example.c -o example
 echo "compiling..."
 touch compile


Makefile Notes

Make assumes that Makefile targets are files in the same directory in which the make command is executed.

If the target file is already there, and its dependencies didn't change, nothing will be done.

"compile" is a dependency of the exec target. "compile" will be executed prior to executing the exec command "./example"

"example.c" is a dependency of the compile target. (It could be on the same line as "compile", but we used the line continuation character "backslash" to put in on a separate line.)

"compile" will be executed only if "example.c" has been modified.

The touch command creates a "compile" target file (if it does not already exist) and effectively updates its last updated timestamp.

Make compares the timestamp of example.c to compile. If example.c has been modified after compile, it will run the "compile" target.

Preface each line of a target body with a single TAB character. (There is a TAB character in front of "./example" in the "exec" target.)

This is a lot of work for managing one source file, but is a huge time saver when there are many source files in a project. Make will only compile the files that have been changed since the last time the compile target has been executed.

Results


$ ls -lrt
total 16
-rw-r--r--  1 lex  staff   64 Jun 30 12:34 example.c
-rw-r--r--  1 lex  staff  108 Jun 30 12:35 Makefile


There are only two files in our directory now.

Run make command


$ make
gcc example.c -o example
echo "compiling..."
compiling...
touch compile
./example
Hello


Results


$ ls -lrt
total 40
-rw-r--r--  1 lex  staff    64 Jun 30 12:34 example.c
-rw-r--r--  1 lex  staff   108 Jun 30 12:35 Makefile
-rwxr-xr-x  1 lex  staff  8496 Jun 30 12:35 example
-rw-r--r--  1 lex  staff     0 Jun 30 12:35 compile


Now, there are 4 files.

Run the newly created executable


$ ./example
Hello


./example.c

Add ", World!" to the output.

#include
int main()
{
 printf ("Hello, World!\n");
 return 0;
}



$ ls -lrt
total 40
-rw-r--r--  1 lex  staff   108 Jun 30 12:35 Makefile
-rwxr-xr-x  1 lex  staff  8496 Jun 30 12:35 example
-rw-r--r--  1 lex  staff     0 Jun 30 12:35 compile
-rw-r--r--  1 lex  staff    72 Jun 30 12:38 example.c


Now, "example.c" has a more recent timestamp than the "compile" file.


$ make
gcc example.c -o example
echo "compiling..."
compiling...
touch compile
./example
Hello, World!


Summary

  • Make ran the "compile" target, because it was the first target listed in the Makefile
  • Make ran the "compile" target, because it was a dependency of the "exec" target
  • Make compared the compare file's timestamp to its dependency "example.c" and ran it because example.c has a more recent timestamp.


More Complicated Scenarios

This has been a very simple, contrived example to show how a Makefile works.

In order to handle more source files, make allows you to use macros, wildcard pattern matching and string substitution features to automatically include files without modifying your Makefile.

References

http://en.wikipedia.org/wiki/Make_(software)
http://www.gnu.org/software/make/manual/make.html

This work is licensed under the Creative Commons Attribution 3.0 Unported License.

Sunday, June 29, 2014

Upgrading from ruby 2.1.1 to 2.1.2 on OSX

Follow instructions in post Upgrading to ruby 2.1.1 on OSX

Commands to upgrade ruby via rbenv


$ (RUBY_CONFIGURE_OPTS=--with-readline-dir="/usr/lib/libreadline.dylib" rbenv install 2.1.2)
$ rbenv global 2.1.2
$ rbenv rehash
$ gem install bundler
$ rbenv rehash


Notes

rbenv rehash should be run after every gem install. You can install the rbenv-gem-rehash plugin to avoid having to do this step all the time.

Results


$ ruby -v
ruby 2.1.2p95 (2014-05-08 revision 45877) [x86_64-darwin13.0]


Side Effects

This upgrade resolves the bigdecimal segmentation fault: ruby/2.1.0/bigdecimal/util.rb:39: [BUG] Segmentation fault

References

https://bugs.ruby-lang.org/issues/9657

This work is licensed under the Creative Commons Attribution 3.0 Unported License.

Monday, June 16, 2014

Color Code Directories in IntelliJ or RubyMine

For many projects, I'll create a "lex" directory with temporary files and notes and such.

Some of those files are some times source code.

When I search, some times I want to see that code, but every time I want to know whether the file I'm looking at in the IDE is from the "lex" directory. (That way, I can prevent myself from accidentally working on temporary files.)

Here's my solution... to use Color Coded Directories in the IDE.

Create a Custom Scope

  • Preferences > Scopes (in IDE main menu)
  • Click "+" (in the upper right hand side)
  • Name your scope (in my example I'll name it "lex" and make it a local scope)
  • Click the twistie icon in the directories control and select directory(s) to color code.
  • In this example, I' chose the "lex" directory, that is at the root to the project
  • Click

Color Code Custom Scope

  • Preferences > File Colors
  • Click "+" at the bottom left of the Shared Colors pane.
  • Choose "lex" in the Scope dropdown
  • Choose a color, like "Orange"


Now, all files and directories in the Project Explorer under the "lex" directory will have an Orange background color.

Also, when you open files from the "lex" directory, you'll know it because their file tabs will be Orange.

Not only that, but when you click Command+B to get a dropdown list of references, those selections will also be color coded if they are coming from a file under the "lex" directory.

This is my favorite IntelliJ/Rubymine Feature :-)


References

http://www.jetbrains.com/idea/
http://www.jetbrains.com/ruby/

Saturday, June 14, 2014

p4merge (git Merge Tool)


brew cask install p4merge

git config --global merge.tool p4mergetool
git config --global mergetool.p4mergetool.trustExitCode false
git config --global mergetool.p4mergetool.cmd "$HOME/Applications/p4merge.app/Contents/Resources/launchp4merge \$PWD/\$BASE \$PWD/\$REMOTE \$PWD/\$LOCAL \$PWD/\$MERGED"
git config --global difftool.p4mergetool.cmd "$HOME/Applications/p4merge.app/Contents/Resources/launchp4merge \$LOCAL \$REMOTE"
git config --global difftool.sourcetree.cmd "$HOME/Applications/p4merge.app/Contents/Resources/launchp4merge \$LOCAL \$REMOTE"
git config --global difftool.sourcetree.path ""
git config --global mergetool.sourcetree.cmd "$HOME/Applications/p4merge.app/Contents/Resources/launchp4merge \$PWD/\$BASE \$PWD/\$REMOTE \$PWD/\$LOCAL \$PWD/\$MERGED"
git config --global mergetool.sourcetree.trustexitcode true


To compare differences between local and remote repo


git difftool `current-git-branch-name` origin/master -Y


Note

The "-Y" means, "Open all the p4merge diff windows without asking me each time it's okay to do so."


References

Thursday, June 12, 2014

Handy Git Aliases


git config --global alias.accept-remote-diffs 'merge origin/master'
git config --global alias.acp '!f() { git add-commit "$1" && git push; }; f'
git config --global alias.acpom '!f() { git add-commit "$1" && git push -u origin master; }; f'
git config --global alias.acpcb '!f() { git add-commit "$1" && git push origin `current-git-branch-name`; }; f'
git config --global alias.add-all '!git add-updated && git add-untracked'
git config --global alias.add-commit '!f() { git add-all && git commit -m "$1"; }; f'
git config --global alias.add-commit-pristine '!f() { git-add-commit-pristine }; f'
git config --global alias.add-untracked '!f() { git-add-untracked }; f'
git config --global alias.add-updated 'add --update :/'
git config --global alias.apply-gitignore-to '!f() { git rm --cached "$@"; }; f'
git config --global alias.clear-alias '!f() { git config --global --unset alias."$@"; }; f'
git config --global alias.clobber-this-branch '!f() { (CURRENT_BRANCH_NAME=`current-git-branch-name`; if [ $CURRENT_BRANCH_NAME = "master" ]; then echo "Cannot run this on master branch" && exit 1; fi; git delete-remote-branch $CURRENT_BRANCH_NAME; git checkout master; git delete-local-branch $CURRENT_BRANCH_NAME;); }; f'
git config --global alias.config-add-remote-origin '!f() { git remote rm origin 2>/dev/null; git remote add origin "$@"; }; f'
git config --global alias.config-make-pulls-merge 'config branch.master.rebase false'
git config --global alias.config-make-pulls-rebase 'config branch.master.rebase true'
git config --global alias.config-onetime-email '!f() { git config --global user.email "$@"; }; f'
git config --global alias.config-onetime-username '!f() { git config --global user.name "$@"; }; f'
git config --global alias.config-only-push-current-branch 'config --global push.default tracking'
git config --global alias.config-project-defaults '!f() { git config-add-remote-origin git@$REMOTE_GIT_ACCOUNT/$1.git; git config-only-push-current-branch; git config-make-pulls-rebase; }; f'
git config --global alias.config-remote-origin-push-head 'config remote.origin.push HEAD'
git config --global alias.create-and-switch-to-branch '!f() { create-git-branch "$@" 2>/dev/null; git config branch."$@".remote origin; git config branch."$@".merge refs/heads/"$@"; }; f'
git config --global alias.create-and-switch-to-new-empty-branch '!f() { git symbolic-ref HEAD refs/heads/$@;rm .git/index;git clean -fdx;echo "\nAdd files, then run: $ git add-commit \"YOUR_MSG\"; git push origin $@\n"; }; f'
git config --global alias.create-branch2 '!f() { create-git-branch2 "$@"; }; f'
git config --global alias.create-local-branch 'checkout -b'
git config --global alias.create-new-repo '!f() { mkdir "$@"; cd "$@"; touch README.md; git init; git add README.md; git commit -m "first commit"; git remote add origin git@"$REMOTE_GIT_ACCOUNT"/"$@".git; }; f'
git config --global alias.delete-alias '!f() { git config --unset alias."$@"; git config --global --unset alias."$@"; }; f'
git config --global alias.delete-local-branch 'branch -d'
git config --global alias.delete-remote-branch 'push origin --delete'
git config --global alias.delete-unstaged '!f() { (echo "";echo "THE FOLLOWING FILES WILL BE DELETED:";git diff --name-only; echo "";echo "ARE YOU SURE? (CTRL+C TO ABORT --OR-- ENTER TO CONTINUE...)";read x;set -x;`git diff --name-only`|xargs rm); }; f'
git config --global alias.delete-untracked '!f() { (echo "";echo "THE FOLLOWING FILES WILL BE DELETED:";git clean -f --dry-run; echo "";echo "ARE YOU SURE? (CTRL+C TO ABORT --OR-- ENTER TO CONTINUE...)";read x; echo "";echo "THE FOLLOWING DIRECTORIES WILL BE REMOVED:";git clean -f -d --dry-run; echo "";echo "ARE YOU SURE? (CTRL+C TO ABORT --OR-- ENTER TO CONTINUE...)";read x;set -x;git clean -f; git clean -f -d); }; f'
git config --global alias.diff-inline 'diff --word-diff'
git config --global alias.diff-remote-master '!f() { git difftool origin/master `current-git-branch-name` -Y; }; f'
git config --global alias.diff-stage-master '!f() { git difftool master `current-git-branch-name` -Y; }; f'
git config --global alias.discard-changes-to-unstaged-file '!f() { git checkout -- "$@"; }; f'
git config --global alias.discard-local-changes '!f() { git reset --hard origin/master && git pull origin master; }; f'
git config --global alias.fetch-and-show-diffs '!git fetch origin && git diff origin/master & echo "Manually merge conflicts. Then, run: $ git accept-remote-diffs"'
git config --global alias.go-to-new-repo '!f() { git link-to-new-repo "$@"; cd "$@"; }; f'
git config --global alias.init-gh-pages '!f() { git symbolic-ref HEAD refs/heads/gh-pages && rm .git/index && git clean -fdx && echo "hello, gh-pages" > index.html; git acpcb "initial gh-page";  }; f'
git config --global alias.link-to-new-repo '!f() { echo "Git repo: $REMOTE_GIT_ACCOUNT/$@.git must already exist."; echo "CTRL+C TO ABORT --OR-- ENTER TO CONTINUE...";read x; mkdir "$@"; cd "$@"; touch README.md; git init; git add README.md; git commit -m "add empty readme file"; git config-project-defaults "$@"; git push -u origin master; echo "You just created a new local repo ($@) that is linked to $REMOTE_GIT_ACCOUNT/$@.git"; }; f'
git config --global alias.list-aliases '!f() { git config --get-regexp alias; }; f'
git config --global alias.list-configs '!f() { git config --list; echo ""; echo "Your git config file: $HOME/.gitconfig"; }; f'
git config --global alias.list-local-branches 'branch'
git config --global alias.list-remote-branches 'branch -r'
git config --global alias.list-unstaged-filenames '!f() { (git diff --name-only); }; f'
git config --global alias.merge-feature-branch-into-master '!f() { (CURRENT_BRANCH_NAME=`current-git-branch-name`; git checkout master; git merge $CURRENT_BRANCH_NAME; git status; echo ""; echo "If no problems, then run: $ git push" ); }; f'
git config --global alias.merge-feature-branch-to-remote-master '!f() { git push origin `current-git-branch-name`:master; }; f'
git config --global alias.merge-feature-branch-to-stage-master '!f() { git checkout -B master `current-git-branch-name`; }; f'
git config --global alias.pretty-log "log --graph --abbrev-commit --decorate --date=relative --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(bold yellow)%d%C(reset)' --all"
git config --global alias.push-current-branch-to-another '!f() { echo "Assumes you have already added and committed files to 'from-branch' (and your remote is named 'origin')."; echo "CTRL+C TO ABORT --OR-- ENTER TO CONTINUE...";read x; git push origin $1:$2; }; f'
git config --global alias.push-local-branch "push origin `current-git-branch-name`"
git config --global alias.rebase-onto-master 'rebase origin/master'
git config --global alias.rename-local-git-branch '!f() { git branch -m $1 $2; }; f'
git config --global alias.show-commits-that-exist-in-master 'cherry -v master'
git config --global alias.show-local-branches 'branch'
git config --global alias.show-local-log 'log --oneline --decorate'
git config --global alias.show-log-graph 'log --graph --decorate --pretty=oneline --abbrev-commit master origin/master master'
git config --global alias.show-log-with-tags 'log --oneline --decorate'
git config --global alias.show-remote-log "log --graph --decorate --pretty=oneline --abbrev-commit master origin/master `current-git-branch-name`"
git config --global alias.show-sha1-branch '!f() { git branch -a --contains "$@"; }; f'
git config --global alias.show-sha1-tag '!f() { git name-rev --name-only "$@"; }; f'
git config --global alias.switch-to-anothers-branch '!f() { git checkout -t "$@"; }; f'
git config --global alias.switch-to-branch '!f() { git checkout "$@"; }; f'
git config --global alias.switch-to-master-branch 'checkout master'
git config --global alias.undo-all-working-dir-changes-including-new-files '!f() { echo "ARE YOU SURE? (CTRL+C TO ABORT --OR-- ENTER TO CONTINUE...)";read x; git reset --hard; git clean -f -d; git clean -f -x -d; }; f'
git config --global alias.undo-last-git-commit-and-delete-local-changes-too '!f() { git reset --hard HEAD^; git push -f; }; f'
git config --global alias.undo-last-git-commit-but-keep-local-changes 'reset --soft HEAD^'
git config --global alias.untracked 'ls-files --other --exclude-standard'
git config --global alias.update-comment-for-unpushed '!f() { git commit --amend -m "$1"; }; f'
git config --global alias.wipe-local-master-replace-with-remote '!git clean -d -x -f && git fetch --all && git reset --hard origin/master'


Notes

Error on Linux

If you get an error mentioning a problem with ":/" when running git acp, likely when you are on a linux operating system, then replace the following git config:


git config --global alias.add-all '!git add -A'


Simple workflow

Create a local feature branch and switch your local workspace to point to it.


git create-local-branch new_feature


Make changes to your local source code.

Commit your changes to your local repo.


git commit -a


This will open your editor where you can see the files being committed and add your commit comment (to the first line).

Note that if you don't want to add every file you've been working on then add each file individually with git add <FILENAME> and then run git commit to commit add your commit comment.

Push your changes to your remote repo, e.g. github.


git push-local-branch


If you are using remote git repo features, like git workflow, now is the time to go to your remote repo and create a pull request.

Your pull request will hopefully pass peer code review. You may need to read comments from peers and perform fixes that you will subsequently push up to this branch and eventually all will be good and your merge master will merge your branch (and may also delete your remote branch to keep things clean on the server.)

View a list of all branches you're working on


git list-local-branches


Delete remote branch


git delete-remote-branch new_feature


Delete local branch


git delete-local-branch new_feature


link-to-new-repo

After you create a git repository, e.g., on github.com or bitbucket.org, this should probably be the first command you run.


$ git link-to-new-repo golang-samples
Git repo: github.com:l3x/golang-samples.git must already exist.
CTRL+C TO ABORT --OR-- ENTER TO CONTINUE...

Initialized empty Git repository in /Users/lex/dev/go/golang-samples/.git/
[master (root-commit) 6fd5651] first commit
 1 file changed, 0 insertions(+), 0 deletions(-)
 create mode 100644 README.md
error: Could not remove config section 'remote.origin'
You just created a new local repo (golang-samples) that is linked to github.com:l3x/golang-samples.git

You can safely ignore the error: Could not remove config section 'remote.origin' message; There were no previous remote origins since this is the first time you initialized your local git repo.

You should make sure that your public key in ~/.ssh is properly configured.

This command assumes you have the environment variable (REMOTE_GIT_ACCOUNT) set to your repo:username.

You can run this command in its own shell and set REMOTE_GIT_ACCOUNT just before running the git command as follows:

(export REMOTE_GIT_ACCOUNT=bitbucket.org:username && git link-to-new-repo reponame)


This command performs the same commands (and a few more goodies) as you might find in the Create a new repository on the command line help section at your remote git repo:

touch README.md
git init
git add README.md
git commit -m "first commit"
git remote add origin https://github.com/l3x/golang-samples.git
git push -u origin master


wipe-local-master-replace-with-remote

wipe-local-master-replace-with-remote has a long alias for a reason. It is destructive and you really need to understand that all local files will be removed (and replaced with the remote files) before running this one.

acp

If you run $ git acp 'my commit message' without first setting the upstream origin, then you'll get an error like this:

 1 file changed, 1 insertion(+)
 create mode 100644 index.html
fatal: The current branch gh-pages has no upstream branch.
To push the current branch and set the remote as upstream, use

    git push --set-upstream origin gh-pages


Solution: Create/initialize your local repo using the $ git link-to-new-repo <PROJECT_NAME> command and it will set your git origin for you.

fatal: The current branch master has multiple upstream branches

If you run $ git push and get an error like this:

$ git push
fatal: The current branch master has multiple upstream branches, refusing to push.

Solution: Run the following command $ git config-remote-origin-push-head and try again.

Sometimes, when you push to the master branch, without passing any parameters to the git push command, you'll get that error.

switch-to-anothers-branch

When you need to pull another team member's branch into your workspace (to work on it) you need to create a local branch. This alias does that and sets up tracking so that you can run git push after making changes.

show-sha1-tag

The name-rev command uses the tilde "~" character to indicate the position of a commit relative to tags in the project. If "5" comes after the "~" character, then that means that this commit is located 5 commits prior to the tag displayed. If you are working off a master branch it may look like this: "master~5". If you are creating release branches and tagging them as such, it may look like this: "tags/v1.2.0~5".

config-only-push-current-branch

By default, git push will push all local branches that have matching remote branch names. Run this alias once (it sets a global config setting) to prevent this default behavior and cause git to only push the branch you are currently working on.

config-make-pulls-rebase

If you are working solo on the master branch or if you are working on a team that works off the same branch, e.g., "development" (and your team is not using github pull requests) and you don't want your git history polluted with merge bubbles, then run this alias once (it sets a global config setting).

config-make-pulls-merge

If you are merging feature branches into a release branch (or have another scenario where you want to see exactly what happened with the merge), then run this alias once (it sets a global config setting).

config-remote-origin-push-head

If you go off the reservation and find yourself working on the master branch and you attempt to run git push without arguments and get an error like the following...

$ git push
fatal: The current branch master has multiple upstream branches, refusing to push.


... then, you should remove the following two lines from the [branch "master"] section in your ~/.gitconfig file

 remote = origin
 merge = refs/heads/master


and run git config-remote-origin-push-head


Errors

Unable to create git alias

If you get the following error message...

error: could not lock config file .git/config: No such file or directory


...when attempting to create a git alias, then run the following commands:

$ mkdir ~/.git
$ git config-add-global-email-account <YOUR_EMAIL@YOUR_HOST.COM>



Scripts

current-git-branch-name


# Filename: current-git-branch-name
#!/usr/bin/env ruby
# Filename: current-git-branch-name
puts `git branch`.split("\n").select{|i| i.include?('* ')}[0][2..-1]

git-add-untracked


# Filename:  git-add-untracked
(IFS=$'\n'; files=(`git untracked`); for file in "${files[@]}"; do git add $file;  if [ "$?" != "0" ]; then echo "<< run dos2unix  for this file. Then, git add ;git commit --amend --no-edit\n"; fi; done)
if [ "$?" != "0" ]; then
  echo "If you see something like:  fatal: CRLF would be replaced by LF in FILE_NAME."
  echo "Then run:  $ dos2unix on each FILE_NAME  ... and try again."
fi

git-add-commit-pristine


# Filename:  git-add-commit-pristine
MSG=$1
MY_NAME=$(basename $0)
if [ "$MSG" == "" ]; then
    echo "Usage:  $MY_NAME "
    echo ""
    echo "Example:  $MY_NAME 'update readme'"
    exit 1
fi
git add-commit "$MSG" && git fetch && git rebase-from-master && git merge-feature-branch-into-master && git push

create-git-branch2


# Filename: create-git-branch2
# Note:     This also replaces ' ' with '-' and lowercases the branch name
# Note:     This is named "create-git-branch2" b/c git-extras has a script named git-create-branch

BRANCH_NAME=$1
if [ "$BRANCH_NAME" == "" ]; then
    BRANCH_NAME=$(date +%Y%b%d-%H%M)
else
   IFS=' '
   ALL_ARGS="$*"
   echo "ALL_ARGS: $ALL_ARGS"
   BRANCH_NAME=`echo $ALL_ARGS | tr '[:upper:]' '[:lower:]' | tr ' ' '-'`
   echo "BRANCH_NAME: $BRANCH_NAME"
fi

if ( git show-ref --verify --quiet refs/heads/$1 ); then 
    echo "ERROR - Branch ($BRANCH_NAME) already exists." 
    exit 1
else 
    if ( git show-ref --verify --quiet refs/remotes/origin/$BRANCH_NAME); then 
        echo "ERROR - Remote branch ($BRANCH_NAME) already exists." 
        exit 1
    else
        echo "Switching to master..."
        git checkout master 

        echo "Fetching origin..."
        git fetch origin

        echo "Pulling master..."
        git pull

        echo "Creating new branch ($BRANCH_NAME)..."
        git checkout --track -b $BRANCH_NAME 

        echo "Done."
    fi 
fi



Aliases

gcb


alias gcb='git create-and-switch-to-branch


gcb usage


$ gcb feature1
Switching to master...
Your branch is up-to-date with 'origin/master'.
Fetching origin...
Pulling master...
Current branch master is up to date.
Creating new branch (feature1)...
Branch feature1 set up to track local branch master.
Done.


That just created a branch named feature1 and setup the refs so that you can start using git push (without every any having to add -u origin feature1.

git config file after running gcb


feature1 ~/tmp/bogus $ cat .git/config
[core]
 repositoryformatversion = 0
 filemode = true
 bare = false
 logallrefupdates = true
 ignorecase = true
 precomposeunicode = true
[remote "origin"]
 url = git@github.com:l3x/bogus.git
 fetch = +refs/heads/*:refs/remotes/origin/*
[branch "master"]
 remote = origin
 merge = refs/heads/master
[branch "feature1"]
 remote = origin
 merge = refs/heads/feature1





Global Git Config

Perform git clones using https rather than the git protocol.


git config --global url."https://".insteadOf git://



References

http://lexsheehan.blogspot.com/search?q=add-commit
http://stackoverflow.com/questions/1125968/force-git-to-overwrite-local-files-on-pull
http://stackoverflow.com/questions/2514270/how-to-check-for-changes-on-remote-origin-git-repository
http://stackoverflow.com/questions/5772192/git-how-can-i-reconcile-detached-head-with-master-origin
http://mislav.uniqpath.com/2010/07/git-tips/

This work is licensed under the Creative Commons Attribution 3.0 Unported License.

Tuesday, June 3, 2014

Suppress JSHint for Entire File

There a a few ways to suppress jshint warnings for entire files.

File By File

Prepend a file with the following line:

// jshint ignore: start



All At Once

My preferred day is to list all files individually in a jshint config file.

Example contents of .jshintignore file:

app/scripts/init.js
app/scripts/main.js
app/scripts/util/util.js



References

http://lexsheehan.blogspot.com/2014/05/suppress-jshint-warnings.html

Monday, June 2, 2014

git delete-untracked

Want to delete all files that have not been added to your git repo?

Create a Git Alias

You can create a global git aliases like this:

$ git config --global alias.delete-untracked '!f() { (echo "";echo "THE FOLLOWING FILES WILL BE DELETED:";git clean -f --dry-run; echo "";echo "ARE YOU SURE? (CTRL+C TO ABORT --OR-- ENTER TO CONTINUE...)";read x; echo "";echo "THE FOLLOWING DIRECTORIES WILL BE REMOVED:";git clean -f -d --dry-run; echo "";echo "ARE YOU SURE? (CTRL+C TO ABORT --OR-- ENTER TO CONTINUE...)";read x;set -x;git clean -f; git clean -f -d); }; f'


See reference link below for more handy git aliases.


References

http://lexsheehan.blogspot.com/2014/05/git-add-update.html