This Git for Windows upgrade from v2.8 to v2.11 is an
unsuccessful attempt to fix a Jekyll preview error on
my another blog triggered by the command jekyll serve
for
local preview.
After the update, I can no longer input letters with accents. Since the name of some mathematical theorems have accents, like l’Hôpital’s Rule. It would be very inconvenient if the internation keyboard can’t be used in Git Bash.
In Git Bash, locale
returns several lines. The first one says
LANG=C
. After viewing the list with locale -a
, I’ve finally
chosen the most common option with the character encoding UTF-8. To
make this change permanent for one user, add the last line into
~/.bashrc
.
1
2
# Change Locale Permanently
export LANG=en_US.utf8
Many popular URL shorteners like Bitly and Google URL Shortener won’t afftect my SEO, so I can use shortened URLs in the markdown syntax for Octopress codeblocks to save disk space.1
Do URL Shorteners Impact your SEO? by David Amerland. ↩
I attempted to manually fix a problem in the first post in this series half a year ago.
I have just updated the Jekyll source code for Blog 2.
[owner@localhost ~/blog2]$ git pull jekyll master
remote: Counting objects: 37, done.
remote: Total 37 (delta 10), reused 10 (delta 10), pack-reused 27
Unpacking objects: 100% (37/37), done.
From github.com:plusjade/jekyll-bootstrap
* branch master -> FETCH_HEAD
3a34785..8193869 master -> jekyll/master
Removing sitemap.txt
Auto-merging _includes/JB/setup
CONFLICT (content): Merge conflict in _includes/JB/setup
Auto-merging _config.yml
Automatic merge failed; fix conflicts and then commit the result.
How to repair this failed merge?
In the file _includes/JB/setup
, I deleted the HEAD
part, and
adopted the official changes in the remote repository for Jekyll.
Then, everything should be fine.
I hadn’t used Vim on my GNU/Linux desktop for a month. When I used it again, an error message was shown on the screen.
[owner@localhost ~]$ vi
Error detected while processing
/home/owner/.vim/bundle/nerdtree/plugin/NERD_tree.vim:
line 153:
E117: Unknown function: nerdtree#ui_glue#setupCommands
Error detected while processing function nerdtree#postSourceActions:
line 2:
E117: Unknown function: nerdtree#ui_glue#createDefaultBindings
Press ENTER or type command to continue
Since I was occupied with another blog, thinking that the problem would be quickly fixed by an update of the NERD tree, a Vim plugin for showing a file tree in a sidebar, I didn’t want to find out the cause.
During this Vundle update, an exclamation mark with red background
was displayed on the LHS of the item Plugin 'scrooloose/nerdtree'
in
the list contained in the status bar. I then checked Vundle’s update
log.
[2016-08-12 15:18:40] Plugin scrooloose/nerdtree
[2016-08-12 15:18:40] $ cd '/home/owner/.vim/bundle/nerdtree' && git pull && git submodule update --init --recursive
[2016-08-12 15:18:40] > error: object file .git/objects/2e/2b649232d6ae4d02d74793e5da0ee08480ad8d is empty
[2016-08-12 15:18:40] > error: object file .git/objects/2e/2b649232d6ae4d02d74793e5da0ee08480ad8d is empty
[2016-08-12 15:18:40] > fatal: loose object 2e2b649232d6ae4d02d74793e5da0ee08480ad8d (stored in .git/objects/2e/2b649232d6ae4d02d74793e5da0ee08480ad8d) is corrupt
[2016-08-12 15:18:40] > fatal: The remote end hung up unexpectedly
[2016-08-12 15:18:40] >
While I was trying to update this plugin manually by typing in Git commands in bash, the electricity supply of my desktop went off suddenly. After it had been switched on again, I tried typing in the commands again, and I got the same error.
How can the Git repository be restored to its previous state, so that it’s intact?
This problem can be fixed by simply undoing all changes done to the
directory .git/
. First, a list of recently changed files is needed,
and find
can be used for this purpose. I searched “ls filter by
time”, then this question about ls
on Unix & Linux
Stack Exchange appeared in the search results. After reading the
first answer, I tried to find the defective binary objects in
.git/objects
.
[owner@localhost ~/.vim/bundle/nerdtree/.git]$ find . -maxdepth 1 -mindepth 1 \
> -mtime -1 -type d -print -and -exec ls -lt {} \;
./2e
total 20
-r--r--r-- 1 owner owner 0 Aug 12 15:18 2b649232d6ae4d02d74793e5da0ee08480ad8d
-r--r--r-- 1 owner owner 256 May 12 20:38 c9b3dd9d6b8d11f2a3c12924f88588a846517d
./7e
total 44
-r--r--r-- 1 owner owner 341 May 12 20:38 8be22b1d5052e9140fc7c7b840755980cb960
9
-r--r--r-- 1 owner owner 49 May 12 20:38 9492c9f3b3b463114c0b6308a8ccd46ce3869
2
-r--r--r-- 1 owner owner 3029 Nov 1 2014 12c042bb8f5ab387a2bd0aabcfe30fce25027
f
./a0
total 20
-r--r--r-- 1 owner owner 0 Aug 12 15:43 019ff4d6b033f37efd9b1a99daf6c9797796b1
-r--r--r-- 1 owner owner 468 May 12 20:38 b89b83d8cd02f8043840a48b0b2cf3724bee1c
./29
total 20
-r--r--r-- 1 owner owner 0 Aug 12 15:43 24ab207162ca18cf5844d00b351ade1b5122f6
-r--r--r-- 1 owner owner 342 May 12 20:38 0935cab8f1e7dec23bb3bda0e2f7dd84c867d9
./38
total 20
-r--r--r-- 1 owner owner 0 Aug 12 15:43 d79fd1123213f2ceb3d6c32e8dad42bd587ec8
-r--r--r-- 1 owner owner 55 May 15 2015 569aab72ab0cbf466c40658ab9a3d86b55263e
./d7
total 8
-r--r--r-- 1 owner owner 0 Aug 12 15:43 9f81cd6e309fa01e063f3e12fb7615e712d7f4
./2a
total 36
-r--r--r-- 1 owner owner 0 Aug 12 15:43 a3bece220f147f85172fe43430d069276d835
c
-r--r--r-- 1 owner owner 7025 Jun 24 2015 f07ddbaf243cef8de791b45e7ff4232025a93
6
-r--r--r-- 1 owner owner 277 May 15 2015 a1964c1ba8fd40f3fdebf64efd0ba3756115a
f
./b7
total 20
-r--r--r-- 1 owner owner 0 Aug 12 15:43 23fee57c918ba3fd06057398e0a905fde7b80e
-r--r--r-- 1 owner owner 277 May 15 2015 2300417059ab5c52ac26c318e6b67bcefbe1e2
./c9
total 20
-r--r--r-- 1 owner owner 0 Aug 12 15:43 9312442b0961241eb0de3d6d65893c52f4d9d1
-r--r--r-- 1 owner owner 49 May 15 2015 ab6021b2473c60ba443c5ad197f2e3e3692895
./e8
total 20
-r--r--r-- 1 owner owner 0 Aug 12 15:43 7e67fafb0d6c63b790b37ab46f67cf0654ea22
-r--r--r-- 1 owner owner 466 May 15 2015 258b21d3a02dfcc0c5c10f3ab186763ae0c38b
./4c
total 36
-r--r--r-- 1 owner owner 0 Aug 12 15:43 bfb3869eb16ca691d93e1a3a05d375e87c1c7
7
-r--r--r-- 1 owner owner 57 May 15 2015 be8a2baee075d0935e3af349d85c2553d77bf
8
-r--r--r-- 1 owner owner 6830 Nov 1 2014 df1a366dbdf08c5f7412ff867d859d6818376
4
Objects are grouped according to the first two digits of their Git hash. The following list is easier to read.
[owner@localhost ~/.vim/bundle/nerdtree/.git/objects]$ find . -mindepth 2 \
> -maxdepth 2 -mtime 0 -type f -exec file {} \;
./2e/2b649232d6ae4d02d74793e5da0ee08480ad8d: empty
./7e/e42eb25e86a6825cdba370f20d2e146ed61ae6: empty
./a0/019ff4d6b033f37efd9b1a99daf6c9797796b1: empty
./29/24ab207162ca18cf5844d00b351ade1b5122f6: empty
./38/d79fd1123213f2ceb3d6c32e8dad42bd587ec8: empty
./d7/9f81cd6e309fa01e063f3e12fb7615e712d7f4: empty
./2a/a3bece220f147f85172fe43430d069276d835c: empty
./b7/23fee57c918ba3fd06057398e0a905fde7b80e: empty
./c9/9312442b0961241eb0de3d6d65893c52f4d9d1: empty
./e8/7e67fafb0d6c63b790b37ab46f67cf0654ea22: empty
./4c/bfb3869eb16ca691d93e1a3a05d375e87c1c77: empty
I removed these files and typed git status
.
[owner@localhost ~/.vim/bundle/nerdtree]$ git status
fatal: bad object HEAD
I googled “invalid sha1 pointer in cache-tree”, and read a webpage a
Stack Overflow post on empty Git objects. The command
git fsck --full
can be used to check the integrity of a Git
repository.
[owner@localhost ~/.vim/bundle/nerdtree/.git]$ git fsck --full
Checking object directories: 100% (256/256), done.
Checking objects: 100% (3525/3525), done.
error: HEAD: invalid sha1 pointer 2e2b649232d6ae4d02d74793e5da0ee08480ad8d
error: refs/heads/master: invalid sha1 pointer 2e2b649232d6ae4d02d74793e5da0ee08
480ad8d
error: refs/remotes/origin/HEAD: invalid sha1 pointer 2e2b649232d6ae4d02d74793e5
da0ee08480ad8d
error: refs/remotes/origin/master: invalid sha1 pointer 2e2b649232d6ae4d02d74793
e5da0ee08480ad8d
error: HEAD: invalid reflog entry 2e2b649232d6ae4d02d74793e5da0ee08480ad8d
error: refs/heads/master: invalid reflog entry 2e2b649232d6ae4d02d74793e5da0ee08
480ad8d
error: refs/remotes/origin/master: invalid reflog entry 2e2b649232d6ae4d02d74793
e5da0ee08480ad8d
error: d79f81cd6e309fa01e063f3e12fb7615e712d7f4: invalid sha1 pointer in cache-t
ree
missing blob 2aa3bece220f147f85172fe43430d069276d835c
The above message inspired me to make the following list of files changed due to this failed Git pull.
[owner@localhost ~/.vim/bundle/nerdtree/.git]$ find . -mtime 0 -type f -print
./refs/heads/master
./refs/remotes/origin/master
./FETCH_HEAD
./logs/HEAD
./logs/refs/heads/master
./logs/refs/remotes/origin/master
./ORIG_HEAD
./index
I looked at the relevant files in the folder logs/refs/
. The change
time in Unix timestamp, the old and new commit IDs were found.
I restored these files (including the logs) with the help of these
logs except FETCH_HEAD
and index
.
At this stage, git status
would still throw out an error if it was
invoked. However, since the references to HEAD
and ORIG_HEAD
had
been manually set, git reset --hard HEAD
could restore the Git
repository.
Finally, I could update the NERD Tree.
[owner@localhost ~/.vim/bundle/nerdtree]$ git pull
remote: Counting objects: 11, done.
remote: Total 11 (delta 3), reused 3 (delta 3), pack-reused 8
Unpacking objects: 100% (11/11), done.
From https://github.com/scrooloose/nerdtree
d280b15..2e2b649 master -> origin/master
Updating d280b15..2e2b649
Fast-forward
autoload/nerdtree/ui_glue.vim | 16 ++++++++--------
1 file changed, 8 insertions(+), 8 deletions(-)
-maxdepth
and -mindepth
.-type
)
-mtime [n]
: last modified time equal to n
*24
hours. (rounded down to an integer)
-mtime +[n]
: modified before n
*24
hours.-mtime -[n]
: modified within the last n
*24
hours.-mmin [n]
: modified time calculated in number of minutes
instead of days.-atime [n]
, -amin [n]
: last access time-ctime [n]
, -cmin [n]
: last change of file status-anewer
, -cnewer
, -newer
: followed by filename (-mnewer
doesn’t exist.)-daystart
: use the start of day for calculations. (Preceed
-mtime
)Use -t
flag to sort files using their last modified time in
descending order.
One can find files from a Git SHA1 hash using git ls-tree -r <hash>
.
To search contents in commits, you may refer to a
question about Git on Stack Overflow.
When I wrote my list of low-level commands last year, I
couldn’t understand the role of index
. Now, I know that the
binary objects stored in objets/
and the references can work
independently of index
, which can be re-created by git
write-tree
.
A year ago, I was using msysgit on M$ Win* 7. Its support for Unicode characters isn’t so good, and I can’t write a text file with accents like “café” in the Vim editor that shipped with msysgit. As a result, I needed GVim for editing my $\rm \LaTeX$ documents.
Unluckily, unlike Linux, the GVim can never have forward control. Therefore, I needed to switch windows between GVim and Git Bash.
More importantly, if I want to apply the Linux skills and the tools on M$ Win*, I need portable programs excutable on a USB unless I carry my laptop.
Luckily, the bash shell in Git for Windows has improved a lot. The accents are well supported. Then, I have switched from GVim to the embedded Vim in Git for Windows. Luckily, the setup of Vundle was smooth. Most of the installed plugins work fine in terminal Vim.
In the post Git Portable Home Path, a BAT file is included so
that the home folder and the HOMEDRIVE
environment are automatically
set. Since the same Git repository can be shared among multiple
devices, such as my Linux desktop, my M$ Win* 7 laptop, and my USB
stick, a bare repository is needed for efficient pulling and pushing
of Git commits. Since I work outside home, I place a bare Git repo in
my USB stick. However, for each local Git repository stored in the
USB stick (under ~/local_repo
, a.k.a.
$HOMEDRIVE/PortableGit/home/owner/local_repo
), I need to run the
following command for each time I use Git Bash.
After making some changes on a $\rm \TeX$ file, I compiled the file using Mik$\rm \TeX$ Portable.
$HOMEDRIVE/MikTeXPortable/
.miktex-portable.cmd
.$HOMEDRIVE/PortableGit/home/owner/local_repo
.pdflatex file.tex
.This sounds really slow. The goal is to find a more efficient $\rm \LaTeX$ editing workflow.
That’s not the end. Another bad news came from eu1lmr.fd
. I’ve
got error similar to fengbaobao6’s. The compilation was
stuck at ...\tex\latex\euenc\eu1lmr.fd
. Then an error was shown:
“Fontconfig error: Cannot load config file”.
~/.bashrc
if it doesn’t exist.Searching the error text, I found kounoupis’s answer on
Ask Ubuntu. Even though the export
command didn’t
work for me, I still found his answer informative.
Finally, reading miktex-portable.cmd
, I gave up on investigating the
problem, and added the last line of this file into BASHRC since I have
other important things to do.
1
2
3
@echo off
cd /d %~dp0
miktex\bin\miktex-taskbar-icon.exe
To include Mik$\rm \TeX$ into PATH
, I first extracted $HOMEDRIVE
in the form /f
instead of F:/
. If not, Mik$\rm \TeX$ won’t
work.
Here’s my BASHRC for Git Bash.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
stty -ixon
cd ~
HOMEDRIVE=$(perl -e '($var) = $ENV{HOMEDRIVE} =~ /([A-Z]):/; print "/".lc($1)')
if [ $(perl -e '($var) = $ENV{PATH} !~ /tex/i; print STDOUT $var') ]
then
echo "No LaTeX found! Added $HOMEDRIVE/MikTeXPortable/miktex/bin
to path."
PATH=$PATH:$HOMEDRIVE/MikTeXPortable/miktex/bin
echo "IMPORTANT: Close MikTeX Taskbar icon before exit."
echo "Otherwise this shell WON'T close."
miktex-taskbar-icon
fi
loc_repo=(
'resume2015'
)
for f in ${loc_repo[@]}; do
cd $f
git remote set-url origin $HOMEDRIVE/$f.git
cd -
done
If the setup is correct, then \ll
in $\rm \LaTeX$-Suite should
automatically trigger the $\rm \LaTeX$ compilation. I give up on
finding ways to open a viewer with \lv
since I can use the keyboard
to switch to a web browser to see the compiled PDF file without
installing another PDF viewer in my USB stick.
I’ve learnt some Perl and bash after writing this BASHRC.
$ENV{HOMEDRIVE}
for extracting the environment variable
HOMEDRIVE
./(regex_pat)/;
for extracting matching string to capture
groups $1
, $2
… (The ()
around regex_pat
is
crucial.).
for string concatenation.lc()
for converting a string to lowercase.Knowing some regular expressions in Vim, I hope to apply these concepts to Perl so that I can search and replace some simple strings directly in base without having to open the editor.
As a Vim user, the class of special characters in Perl is more
natural than that of sed
.
In the previous post, the list of Git commit messages containing
the string “HTTPS” is the main focus. However, the alignment of this
list isn’t good: in the column representing the day, the data can be
either one or two digit. Though I can still extract information with
awk '{print $[col_num]}'
, it’s better to fix the alignment.
$ git log -2 --grep="HTTPS" --pretty="%h %cd %s"
7400582 Sun Mar 20 20:19:47 2016 +0800 Updated my Rakefile with HTTPS
b6f4f1f Mon Feb 8 00:45:02 2016 +0800 A new article about Flair, Octopress and HTTPS
Searching “perl intro” online, one can easily find some basic Perl scripts. I tried to issue some simple one-line Perl command to save time, but I couldn’t easily find them. Thanks to a webpage by Philippe Bruhat, I managed to starting using Perl. I jot them down here.
$ perl -e 'print "hello \n"' # single quote outside
hello
$ perl -e "\$str='abc'; print \$str;" # escape $, no EOL
abc
$ perl -e "$str='test'; print $str.'\n';" # not desired
test\n
$ perl -e '$str="test"; print $str."\n";' # want newlne
test
The -e
flag above stands for “execute”.
Unluckily, I didn’t know how to use system()
nor backticks to pass
output of a command into Perl. After trying a few search keywords,
“perl oneline read command output” worked best for me. It was quite
uncommon that I found the eighth result useful. In the article
Perl One-liners, I found out the answer.
$ for (( i = 1; i <= 10; i++ )); do
echo $i
done | perl -e 'while (<>) {s/(?<!\d)\d{1}(?!\d)/0$&/; print $_}'
01
02
03
04
05
06
07
08
09
10
In fact, the flag -n
can be used to replace the while (<>) {...}
loop. The -p
flag has the function of -n
but also prints the
output. I learnt them from Git manual web page for git-log.
Combine the above observations together.
$ git log -2 --grep="HTTPS" --pretty="%h %cd %s" \
| perl -pe 's/(?<=\u\l\l )\d{1}(?= )/0$&/'
7400582 Sun Mar 20 20:19:47 2016 +0800 Updated my Rakefile with HTTPS
b6f4f1f Mon Feb 08 00:45:02 2016 +0800 A new article about Flair, Octopress and
HTTPS
$&
and
\b
in the replacement. This is the Perl counterpart of &
and
\<
or \>
in Vim respectively.git log
and git show
,
--name-only
: suppress the diff hunk--pretty=format:
display nothingformat
vs tformat
: t
stands for “terminator” (a.k.a. EOL)Each of each flags seems to be useless. Nevertheless, when combined together, they help extract the edited files in a particular commit.
Posting long commands in a blog entry
From the two codeblocks explaining the difference between format
and tformat
in the Git manual, I understand that it’s better to
end each line with a backslash, then continue with the command.
In bash, a >
is then automatically inserted at the beginning of
each line. This is carried from the shell to the source file of
the blog article by copy and paste. I used to think that it’s
good to keep this so that this and the Ubuntu font will give a
sense of reality to the reader. However, this also causes
inconvenience to those who want to try this command. From now on,
I won’t include this character anymore at the beginning of a
long command exceeding 80 characters. I will replace it with a
white space instead.