I finished reading Pragmatic Version Control Using Git by Travis Swicegood, from the beginning of the book through Chapter 7 "Working with Remote Repositories". That should have given me all I needed to figure out how to get back in sync with Icarus Verilog, a project to which I had been contributing and intend to continue. The book's Section 7.3 "Keeping Up-to-Date" is most relevant, but that section is quite thin, less than a page long. I had been having a "git pull" failure. Although the book improved my understanding of Git, for this specific failure I was still on my own.

The pull failure had been

fatal: Entry 'iverilog-vpi.sh' not uptodate. Cannot merge.
Merge with strategy recursive failed.

git-pull can be used to both fetch from and merge with another repository. Since I could not merge, it made sense to me to separate the fetch and merge operations.

I have been focusing on one note in particular from the git-fetch man page:

Note
You never do your own development on branches that appear on the right hand side of a colon on Pull: lines; they are to be updated by git-fetch. If you intend to do development derived from a remote branch B, have a Pull: line to track it (i.e. Pull: B:remote-B), and have a separate branch my-B to do your development on top of it. The latter is created by git branch my-B remote-B (or its equivalent git checkout -b my-B remote-B). Run git fetch to keep track of the progress of the remote side, and when you see something new on the remote branch, merge it into your development branch with git pull . remote-B, while you are on my-B branch.

I had been doing my own development on a local branch called v0_8-branch. To my understanding, git-pull from the central repository of the Icarus Verilog project resulted in a merge to this local v0_8-branch. I didn't know exactly what "right hand side of a colon on Pull: lines" meant, but I suspected that this referred to my local v0_8-branch.

Listing all variables set in the config file revealed the following interesting ones:

remote.origin.url=git://icarus.com/~steve-icarus/verilog
remote.origin.fetch=+refs/heads/*:refs/remotes/origin/*
branch.master.remote=origin
branch.v0_8-branch.remote=origin

Results such as the following have bothered me:

jesus% git status
# On branch v0_8-branch
# Your branch and 'origin/v0_8-branch' have diverged,
# and have 10 and 35 different commit(s) each, respectively.
...

As for "have a separate branch my-B to do your development on top of it", I felt that my local v0_8-branch needed to have my development removed. But first, it was necessary to preserve that development on something like my-B.

git branch my-v0_8-branch v0_8-branch
would create the my-v0_8-branch branch from my local v0_8-branch branch.

Before doing that, I put my local v0_8-branch in order (i.e. verify then commit changes) as follows.

jesus% ./autoconf.sh
Autoconf in root...
Can't locate object method "path" via package "Request" at /usr/local/share/autoconf/Autom4te/C4che.pm line 69, line 111.
...

jesus% gmake distclean
Makefile:223: *** multiple target patterns. Stop.
jesus%

I theorized that
~/git/icarus_verilog_cloned/Makefile
was useless (created for Windows when I was developing on Windows; now I'm back on Solaris) and needed to be regenerated.

jesus% setenv CXXFLAGS '-Wall -g -O0'
jesus% ./configure --without-ipal

config.status: creating Makefile
jesus% gmake distclean
dep/main.d:1: *** multiple target patterns. Stop.
jesus%

In order to clean up the dependency files, I decided to build first.

jesus% gmake DEBUGFLAGS=-DDEBUG
dep/main.d:1: *** multiple target patterns. Stop.
jesus% ./configure --without-ipal

config.status: creating Makefile
jesus% gmake distclean
dep/main.d:1: *** multiple target patterns. Stop.
jesus%

That didn't work, so I decided to manually remove the dep directory.

jesus% gmake distclean
for dir in vvp vpi tgt-vvp tgt-edif tgt-fpga libveriuser cadpli; do (cd $dir ; gmake clean); done
gmake[1]: Entering directory `/home/alan/git/icarus_verilog_cloned/vvp'
dep/main.d:1: *** multiple target patterns. Stop.
...

I needed to remove all of the dep directories.

jesus% ./autoconf.sh
Autoconf in root...
Autoconf in vpip...
Can't locate object method "path" via package "Request" at /usr/local/share/autoconf/Autom4te/C4che.pm line 69, line 112.
Autoconf in vpi...
Autoconf in vvp...
Autoconf in tgt-vvp...
Autoconf in tgt-edif...
Autoconf in tgt-fpga...
Autoconf in libveriuser...
Autoconf in cadpli...
Precompiling lexor_keyword.gperf
jesus% rm -rf vpip/autom4te.cache/
jesus% ./autoconf.sh
Autoconf in root...
Autoconf in vpip...
Autoconf in vpi...
Autoconf in vvp...
Autoconf in tgt-vvp...
Autoconf in tgt-edif...
Autoconf in tgt-fpga...
Autoconf in libveriuser...
Autoconf in cadpli...
Precompiling lexor_keyword.gperf
jesus%

So I finally got through Autoconf.

jesus% source ~/Sun/OpenSPARC/OpenSPARCT1.1.6/OpenSPARCT1.cshrc
jesus% cd $DV_ROOT/design/sys/iop/rtl/
/home/johndoe/OpenSPARCT1/design/sys/iop/rtl/: No such file or directory
jesus%

That's the way Sun delivers OpenSPARCT1.cshrc. Obviously, I had neglected to modify it since moving to Version 1.6, so I now set DV_ROOT appropriately for my environment.

jesus% iverilog -v -tfnf -I$DV_ROOT/design/sys/iop/include -cFlist.iop_top -g2 -sOpenSPARCT1 $DV_ROOT/lib/u1/u1.behV $DV_ROOT/design/sys/iop/common/rtl/swrvr_clib.v
tmpdir is /tmp
tmpdir is /tmp
Icarus Verilog version 0.8.6 ($Name: $)
Copyright 1998-2003 Stephen Williams
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA

-v
-C/tmp/ivrlh298c
-C/usr/local/lib/ivl/fnf.conf
--
-
translate: /usr/local/lib/ivl/ivlpp -v -L -D__ICARUS__=1 -f/tmp/ivrlg298c -I/space/OpenSPARC/OpenSPARCT1.1.6/design/sys/iop/include >/tmp/ivlpp_stdout
Icarus Verilog Preprocessor version $Name: $ $State: Exp $
Copyright (c) 1999 Stephen Williams (steve@icarus.com)
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
gdb /usr/local/lib/ivl/ivl
GNU gdb 6.6
Copyright (C) 2006 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and you are
welcome to change it and/or distribute copies of it under certain conditions.
Type "show copying" to see the conditions.
There is absolutely no warranty for GDB. Type "show warranty" for details.
This GDB was configured as "sparc-sun-solaris2.10"...
(gdb) run -v -C/tmp/ivrlh298c -C/usr/local/lib/ivl/fnf.conf -- - Starting program: /usr/local/lib/ivl/ivl -v -C/tmp/ivrlh298c -C/usr/local/lib/ivl/fnf.conf -- - warning: Temporarily disabling breakpoints for unloaded shared library "/usr/lib/ld.so.1"
warning: Lowest section in /lib/libdl.so.1 is .hash at 000000b4
/usr/local/lib/ivl/system.sft: Processing System Function Table file.
Using language generation: IEEE1364-2001
PARSING INPUT
... done, 0.34 seconds.
ELABORATING DESIGN
... done, 1.16 seconds.
RUNNING FUNCTORS
-F synth2 ...
-F synth ...
-F syn-rules ...
-F cprop ...
-F nodangle ...
... 1 iterations deleted 3897 dangling signals and 100 events. (count=3206)
... 2 iterations deleted 3897 dangling signals and 100 events. (count=0)
... done, 0.17 seconds.
CODE GENERATION -t dll
... invoking target_design
** ERROR: Inout ports not supported.
** ERROR: Inout ports not supported.
** ERROR: Inout ports not supported.
** ERROR: Inout ports not supported.
** ERROR: Unsupported logic type: 5.
... done, 1.47 seconds.
STATISTICS
lex_string: add_count=8124 hit_count=16420

Program exited normally.
(gdb)

That's where I left off with Icarus Verilog. I seem to recall that, while I have made a lot of progress with Icarus Verilog support for latches (and Steve Williams has committed all but the most recent work to the central repository), there is some more work to be done on that issue. Some of that work would contribute to Icarus Verilog itself (for everyone). Other work would contribute to the FNF Code Generator (for Verilog-to-JHDL translation). If I'm right that latches are still not fully supported in Icarus Verilog, then Icarus Verilog is now failing silently. As for the above error messages, those are separate issues, and I am committed to resolving them.

So I ran "git commit". But it failed with
Duplicate Signed-off-by lines.

http://willnorris.com/2009/02/git-duplicate-signed-off-by-lines
identifies a "solution" that works, but I can't resist commenting. If Linux wants to map
#!/bin/sh
to Bash Shell, the wisdom of that decision can be debated. I would argue that Solaris is more correct in mapping this shebang to Bourne Shell. Git should not assume it's running on Linux. In my opinion, this is a Git bug. If a Git shell program is going to use Bash features not present in Bourne, its shebang should be explicitly Bash.

Now that my local v0_8-branch branch was functional, it was time to create the my-v0_8-branch branch from it.

As I said, I felt that my local v0_8-branch needed to have my development removed. First, I ran "git log" to identify all commits since last being in sync with Icarus Verilog, commits where I was the author. I wanted to use "git revert" because it keeps a history of everything.

This worked for some commits. But the following commit from 2008-09-12, for example, whose commit message was "Merge branch 'v0_8-branch' of git://icarus.com/~steve-icarus/verilog into v0_8-branch", resulted in

fatal: Commit d7374e89cbf2ab31900f03410a75d3197051049a is a merge but no -m option was given.

I find the -m option of git-revert to be confusing. It seems to me that such a merge commit from the central Icarus Verilog repository would have a parent that differs (parent from remote central repository) and a parent that does not differ (parent from local repository). So what change would I want to reverse? Recall that I'm trying to remove my development only. So I skip reverting these merge commits, right? Even if I wanted to revert them, what is a "parent number"?

Using "git diff", I viewed the changes between origin/v0_8-branch and v0_8-branch. I found that the patch command that comes with Solaris is incompatible with Git's output ("I can't seem to find a patch in there anywhere") and was forced to use GNU patch.

Finally, I finished making v0_8-branch match origin/v0_8-branch. But now

jesus% git status
# On branch v0_8-branch
# Your branch and 'origin/v0_8-branch' have diverged,
# and have 92 and 36 different commit(s) each, respectively.
...

The contents matches, but the branches are still divergent because of how they got to where they are!

What's next? Back to that note from the git-fetch man page, with some text substitutions I think I was told to run "git fetch" to keep track of the progress of the remote side, and when I see something new on the remote branch, merge it into my development branch with "git pull . v0_8-branch" while I am on the my-v0_8-branch branch.

jesus% git fetch
remote: Counting objects: 86, done.
remote: Compressing objects: 100% (44/44), done.
remote: Total 44 (delta 35), reused 0 (delta 0)
Unpacking objects: 100% (44/44), done.
From git://icarus.com/~steve-icarus/verilog
291dc52..c9f6bd6 master -> origin/master
cfd0162..89bcbc7 v0_8-branch -> origin/v0_8-branch
bbe037b..24a60ce v0_9-branch -> origin/v0_9-branch
ac78ae3..6ef9243 vvp-net-out-rework -> origin/vvp-net-out-rework
jesus%

But then
git diff v0_8-branch origin/v0_8-branch
showed that my local v0_8-branch no longer matched, even though it did immediately before "git fetch". This surprised me at the time. What's all the fuss about never doing my own development on v0_8-branch if it's not going to track the central repository anyway?

Some of Travis Swicegood's terminology is not consistent with the Git documentation. That was confusing me. I'll try to be clear to my readers by staying consistent with the Git documentation myself.

I came to understand what "git fetch" had done. Data had been copied from Steve's v0_8-branch to my origin/v0_8-branch. "git branch -r" will list ... the remote-tracking branches, and on that list is origin/v0_8-branch. Therefore, origin/v0_8-branch is a remote-tracking branch. In other words, "git fetch" put the data onto the remote-tracking branch.

I had worked to make the local branch, v0_8-branch, match the remote-tracking branch and was frustrated with the discovery that "git fetch" does not assist with that.

The git-pull and git-fetch man pages contain "You never do your own development on branches that appear on the right hand side of a colon on Pull: lines...". Travis Swicegood writes, "You can check out those [remote-tracking] branches like a normal branch, but you should not change them. If you want to make a change to them, create a local branch from them first, and then make your change." I suspect that these two paragraphs are equivalent.

I began to suspect that the work I did on the local branch, v0_8-branch (i.e. to make it match the remote-tracking branch), was a waste of time and that that branch is not needed. My development is on the local branch, my-v0_8-branch. Recall that the local my-v0_8-branch branch was created from the local v0_8-branch branch, before I removed my development from v0_8-branch (i.e. before I made v0_8-branch match origin/v0_8-branch).

Travis Swicegood goes on to write, "Running 'git fetch' updates your [remote-tracking branches]; it doesn't merge the changes into your local branch. You can use 'git pull' if you want to fetch the changes from a remote repository and merge them into your local branch at the same time. " See above where I wrote, "it made sense to me to separate the fetch and merge operations."

It seems that the local branch, v0_8-branch, no longer serves any purpose.

It was about time for me to fully understand what "right hand side of a colon on Pull: lines" means. To do this, I was led to the REMOTES section of the "git-fetch" man page. In particular, I focused on "Named file in $GIT_DIR/remotes". I haven't done anything special, so $GIT_DIR is the ".git" subdirectory at the top level of the working directory of the project. There was no $GIT_DIR/remotes directory, so I created one along with a file for "Named file in $GIT_DIR/remotes". The file's name is "steve" (the owner of the Icarus Verilog project and its central repository).

The command becomes
git fetch steve

Inside the "steve" file, the URL is
git://icarus.com/~steve-icarus/verilog

No Push: line is needed because Steve hasn't granted me that permission. I contribute by means of patches.

As for the Pull: line, that's what I'm currently trying to figure out. The Pull: line in question will describe how to git-fetch,
an operation that I intend to perform to update the remote-tracking branch. To my understanding, such an update is a fast forward update. My first attempt at a Pull: line was

Pull: v0_8-branch:origin/v0_8-branch

I'm pretty confident in the source ref . Note that it refers to Steve's v0_8-branch.

jesus% git fetch steve
From git://icarus.com/~steve-icarus/verilog
* [new branch] v0_8-branch -> origin/v0_8-branch
jesus%

That's not good.

jesus% git branch
* (no branch)
master
my-v0_8-branch
origin/v0_8-branch
v0_8-branch
jesus% ls -l .git/refs/heads/origin/
total 1
-rw-r--r-- 1 alan other 41 2009-07-17 19:41 v0_8-branch
jesus%

.git/refs/heads/origin/
shouldn't even exist, so I reversed the effects of that git-fetch.

The good stuff is on the following list:

jesus% ls -l .git/refs/remotes/origin/
total 14
-rw-r--r-- 1 alan other 41 2007-10-20 14:07 cvshead
-rw-r--r-- 1 alan other 41 2008-09-12 13:12 elaborate-net-rework
-rw-r--r-- 1 alan other 41 2009-01-05 13:27 embedded-vvp
-rw-r--r-- 1 alan other 32 2007-10-20 14:07 HEAD
-rw-r--r-- 1 alan other 41 2009-07-10 11:50 master
-rw-r--r-- 1 alan other 41 2008-07-27 09:47 performance
-rw-r--r-- 1 alan other 41 2007-10-20 14:07 v0_6-branch
-rw-r--r-- 1 alan other 41 2009-07-10 11:50 v0_8-branch
-rw-r--r-- 1 alan other 41 2007-10-20 14:07 v0_8-devel
-rw-r--r-- 1 alan other 41 2009-07-10 11:50 v0_9-branch
-rw-r--r-- 1 alan other 41 2008-07-27 09:47 var-array-rework
-rw-r--r-- 1 alan other 41 2009-01-05 13:27 verilog-ams
-rw-r--r-- 1 alan other 41 2007-10-20 14:07 version0_1
-rw-r--r-- 1 alan other 41 2009-07-10 11:50 vvp-net-out-rework
jesus%

But the most recent git-fetch failed to affect that v0_8-branch. Apparently, the destination ref is implicitly relative to
refs/heads
Can I be explicit?