Git & Mac: Working with Unicode filenames
I had some problems with Git and the file spec/fixtures/ČeskýÁČĎÉĚÍŇÓŘŠŤÚŮÝŽáčďéěíňóřšťúůýž
. After pulling the latest commits, it would show that file as untracked, but adding and committing it would throw error: pathspec 'check in unicode fixture file once again' did not match any file(s) known to git
.
Solution
Install Git version > 1.8.2 using homebrew and set
git config --global core.precomposeunicode true
Done.
Reason
According to the linked Stackoverflow post ...
... the cause is the different im...
How to mirror a git repo to a new remote
Say you want to move a git repository from one remote (perhaps Github) to another (perhaps Gitlab).
If you have the repo checked out, you still should make sure to mirror all branches of the old remote, not only those you happen to have checked our. Otherwise the target repo will become a copy of your current repo, and not the source repo, potentially missing commits. You can use this:
git remote rename origin old-origin
git remote add origin <new-remote>
git fetch old-origin --prune
git push --prune origin +refs/remotes/old-origin/*:r...
Git: How to check out branches that exist on multiple remotes
So you're using multiple remotes that offer the same branch?
$ git branch -a | grep my-branch
remotes/something/my-branch
remotes/origin/my-branch
And when trying to check out that remote branch, it fails for you with an error like this?
$ git checkout my-branch
error: pathspec 'my-branch' did not match any file(s) known to git.
Git usually guesses the remote branch to check out, but when using more than one remote, it seems like it no longer can do that.
Even if the branch is the same on both remotes, you nee...
Git: Delete a branch (local or remote)
To delete a local branch
git branch -d the_local_branch
To remove a remote branch (if you know what you are doing!)
git push origin :the_remote_branch
or simply use the new syntax (v1.7.0)
git push origin --delete the_remote_branch
Note
If you get the error
error: unable to push to unqualified destination: the_remote_branch
The destination refspec neither matches an existing ref on the remote nor
begins with refs/, and we are unable to guess a prefix based on the source ref.
error: failed to push some ref...
Git: How to show only filenames for a diff
When you want to do a git diff
but do not care about the full diff and just want to know which files changed, use the --name-only
switch:
$ git diff --name-only
app/controllers/sessions_controller.rb
app/models/user.rb
features/sign_in.feature
To include some brief information about changed lines, use the --stat
switch:
$ git diff --stat
app/controllers/sessions_controller.rb | 8 +-
app/models/user.rb | 30 ++++
features/sign_in.feature | 136 +++++++++++++++++
T...
Git: undo delete
Assuming you're wanting to undo the effects of git rm
or rm
followed by git add -A
or something similar:
This restores the file status in the index:
git reset -- <file>
then check out a copy from the index
git checkout -- <file>
To undo git add
, the first line above suffices, assuming you haven't committed yet.
Note:
Make sure to use double dashes --
to tell git to checkout a file instead of a branch. This only is relevant for [files having the same name as a branch](https://git-scm.com/docs/git-ch...
Git: "Interactive reverts"
If you need to revert only parts of one or several commits the following workflow can help:
If you need to revert multiple changes, make a branch and squash it afterwards.
For every commit you need to revert, starting at the most recent, do:
git revert -n [COMMIT] #revert, but don't automatically commit
... #fix any conflicts
git reset #unstage all changes
git add -p #this will ask you for every change, whethe...
Dropbox + git = Designer <3
One of the thornier problems in our workflow is knowing when assets are delivered from the designer and keeping them in sync with our application as they change. We used to use e-mail, Skype or sticky notes. The trouble is that the designer's file naming and directory structure were never quite the same as the application's /public/images directory, so direct comparisons were impossible and we ended with a lot bookkeeping to make sure that we didn't lose any changes. Our solution is to clone the project's git repository into a folder inside ...
Git: How to remove ignored files from your repository's directory
When you have files in your .gitignore
they won't be considered for changes, but still you might want to get rid of them, e.g. because they clutter your file system.
While a regular git clean
will ignore them as well, passing the -x
switch changes that:
git clean -x
If you want to see what would happen first, make sure to pass the -n
switch for a dry run:
git clean -xn
Clean even harder by passing the -f
(force cleaning under certain circumstances; I think this is also required by default) or -d
(removes director...
Git: Apply a diff
git apply
allows you to apply a diff onto your HEAD
. Most often you can achieve the same result with a rebase
& merge
.
Example:
master commit1 - commit3
feature-branch \ commit2 - commit4
git checkout feature-branch
git reset --hard commit3
git diff ..commit4 | git apply
master commit1 - commit3
feature-branch \ Unstaged commit 2 & 4
You can also [create a patch and apply it afterwards](https://makandracards.com/makandra/2521-git-how-to...
How to ignore new files or changed files in git
How to ignore new files
Globally
Add the path(s) to your file(s) which you would like to ignore to your .gitignore
file (and commit them). These file entries will also apply to others checking out the repo.
Locally
Add the path(s) to your file(s) which you would like to ignore to your .git/info/exclude
file. These file entries will only apply to your local working copy.
How to ignore changed files (temporarily)
In order to ignore changed files to being listed...
Duplicate a git repository with all branches and tags
In order to clone a git repository including all branches and tags you need to use two parameters when cloning the old and pushing to the new repository respectively:
git clone --bare http://example.com/old-repo.git
cd old-repo
git push --mirror http://example.com/new-repo.git
Of course, the URLs to your repository might look different depending on the protocol used, username required, etc.
For a user git
using the git protocol, it could be git@example.com:repository-namespace/repository.git
Git: How to automatically stage deleted files for commit
When you do a git add .
and have deleted files, git won’t stage them to be commited (as deleted). Use
git add -u
From the git documentation: -u
, --update <filepattern>
Only match against already tracked files in the index rather than the working tree. That means that it will never stage new files, but that it will stage modified new contents of tracked files and that it will remove files from the index if the corresponding files in the working tree have been removed.
If no is given, defa...
Git: Push a new branch and track it immediately
When you create a new branch and push it to origin
, you won't be tracking it. This means a git pull
won't know its remote version.
You could use difficult commands to set up a branch's tracking but it's easier to just push it like this:
git push -u
From the documentation on git push:
-u, --set-upstream
For every branch that is up to date or successfully pushed, add upstream (tracking) reference, used by argument-less git-pull(1) and other commands. For more information, see branch.<nam...
Git: Changing commit messages
To change the commit message of the latest (unpushed, unmerged) commit, you can use
git commit --amend
To change the commit message of an earlier (unpushed, unmerged) commit [COMMIT], you can do
git rebase -i COMMIT~
For a current version of git, you can simply mark the line with "reword", and git will ask you later for the new message.
For older versions:
- mark the line with
edit
- save the file
- do a
git commit --amend
when rebasing stops at the relevant commit git rebase --continue
Git: Force a rejected push
If you modified git's history and the change was already pushed, you will usually get a
! [rejected] my-branch -> my-branch (non-fast-forward)
error, when trying to push.
You can force the push, with
git push --force origin my-branch
Careful:
- You might lose history.
- Unless your git is configured to push only the current branch, you must supply the remote branch name or you will force-push all your branches!
- Anyone else who has already pulled the changes will run into significant trouble.
Only...
Prohibit Git from merging .po-files
Merging .po-files with Git is painful.
There have been attempts of making Git more clever when trying to merge .po-files. I believe however that this is not enough as it can still produce invalid .pos (usually due to double definitions), which can seriously confuse gettext afterwards.
Lacking any more secure solution, I think you should avoid editing po files in different branches at the same time. In order to not accidentally produce invalid merges I additionally ...
How to use Git on Windows with PuTTY
-
Get "PuTTY Link" and "Pageant" (an SSH key agent) from the PuTTY download page.
-
Run
pageant.exe
, find its icon inside your system tray and add your SSH key. -
Open up a
cmd
and put the full path to PuTTY'splink.exe
into theGIT_SSH
environment variable, e.g.:set GIT_SSH=D:\PuTTY\plink.exe
You can then use Git like you would on any sane operating system. Just go ahead and git clone
, git pull
, etc.
Also, you may want to add the environment vari...
Change commit messages of past Git commits
To change a commit message of the most recent (unpushed) commit, you can simply use
git commit --amend -m 'new message'
To change messages of (unpushed) commits further in the past:
git rebase -i [COMMIT BEFORE THE FIRST YOU WANT TO EDIT]
Mark all messages to be changed with "edit".
Git will start the rebasing and stop at every marked commit. For each of those, do a
git commit --amend -m 'new message'
git rebase --continue
Git: Remove information on branches that were deleted on origin
When branches get deleted on origin
, your local repository won't take notice of that.
You'll still have your locally cached versions of those branches (which is actually good) but git branch -a
will still list them as remote branches.
You can clean up that information locally like this:
git remote prune origin
Your local copies of deleted branches are not removed by this.
The same effect is achieved by using (kudos to Julien):
git fetch --prune
You could also set that as a default.
Git: Accessing lost commits
Every time you amend
, rebase
or reset
, git commits get "overwritten".
However, git still allows you to checkout those commits using their SHA1, given you can find it.
One option to do this is
git reflog
# or
git reflog show [BRANCH]
This will show a list of all commits the branch has recently pointed to.
Git might garbage collect those commits eventually, but this should only happen after several weeks.
Git: Diff changes in a long line efficiently
Instead of showing you two lines for each change, Git allows you to highlight changes in a line explicitly:
git diff --word-diff some_file
Hello [-world-]{+universe+}!
(The result is usually colored nicely, the removed part being red and the added text green.)
When doing a diff on a long line, this can be very helpful but you'll still get a less
-like scrolling output that can be unhandy to use.\
You maybe just want the diff put into your terminal:
PAGER='' git diff --word-diff some_file
Git: Define a custom merge driver
The ‘merge.*.driver` variable’s value is used to construct a command to run to merge ancestor’s version, current version and the other branches’ version. The merge driver is expected to leave the result of the merge in the file named with %A by overwriting it, and exit with zero status if it managed to merge them cleanly, or non-zero if there were conflicts.
Git instaweb
Git has a built-in repository viewer for your web browser. a bit similar (but less awesome) than github.
If you have apache installed, simply go to your repository, and enter
git instaweb --httpd apache2
otherwise, simply install lighttpd
and just run
git instaweb
This should open a brower automatically pointing to your repository. If not, try to connect to localhost:1234
.
You can stop the server with
git instaweb --stop