Re: erratic behavior commit --allow-empty

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



From: "Angelo Borsotti" <angelo.borsotti@xxxxxxxxx>
Hi Junio,

It does create one; it just is the same one you already happen to have,
when you record the same state on top of the same history as the
same person at the same time.


No, it does not create one:

Angelo
This is a semantics problem. It is like the confusion as to whether zero is a natural number that can be used in counting.

In this case we have created two commits. However they are, by design and definition, identical to each other for this case of identical content and identical administration fields. They cannot be distinguished.

So when the file system is asked to 'write' the second commit, it (the file system in conjunction with the git code) does a no-op, and reports 'done'.

It is a common (systems) engineering problem. Software engineering usually allows an empty subroutine to exist, while physical engineering wouldn't. Git cannot have two unique but identical commits (a contradiction in terms).

Normally git will create a new (different & unique) commit for each and every commit, but in this special case a second identical commit was 'created', but the uniqueness requirement means it _is_ the same as the first commit.

as you can see from the trace of the execution
of my script, the sha of the commit is the same as that of the other,
which means
that in the .git/objects there is only one such commit object, and not two with the same sha. The meaning of the word "create" is to bring into being something that did not exist before. There is no "creation" if the object already exists.


And how would it help what to insert a sleep for 1 second (or 1 year
for that matter)?  As you said, it reads from the system clock, and
there are millions of systems in the world that have Git installed.
You may record the same state on top of the same history as the same
person on two different machines 5 minutes in wallclock time in
between doing so.  These two machines may end up creating the same
commit because one of them had a clock skewed by 5 minutes.

I understood that the command does not create a new commit if all its data, i.e. tree, committer, ... and date are the same, representing the date with 1 second precision. Sleeping for 1 second guarantees that there is no commit in the repo
that has the same time as the time after the sleep, i.e. that the
command creates
a (new) commit.


What problem are you really trying to solve?  You mentioned
importing from the foreign SCM,

I quoted a piece of the man page of git commit, that states that
--allow-empty bypasses
the safety check that prevents to make a new commit. That piece
incidentally states
that it is "primarily" used by foreign SCM interface scripts. But of
course it can be used
in any script that needs to build a commit on top of another.


You also did not seem to have read what I wrote, or deliberately
ignored it (in which case I am wasting even more time writing this,
so I'll stop).

I did not deliberately ignore what you wrote. I might have missed some
point though.

This does not have anything to do with "--allow-empty"; removing
"the option" would not help anything, either.

I am reporting a problem with --allow-empty, so why you say that this
does not have
anything to do with it?
Removing the option removes a behavior that is not predictable.
Often it is better to remove a feature that turns out to be
inconsistent than to leave it
in the software. Of course a much better avenue is to make it consistent.

Run the following on a fast-enough machine.

I did, and obtained most of the times "I was quick enough" and
sometimes "I was not quick enough", which is the same kind of behavior
of my script.

The problem I am trying to solve is to push to a remote server the
source files only,
while keeping in the local repo both sources and binaries. To do it, I
keep an orphan
branch, say "sources". When I make a commit on the master branch, I make also a commit on the sources one after having un-staged (git rm --cached) the binaries.
The script that does this must cope also with the particular case in
which in the commit
on the master branch there are no sources. Basically the script does:

# this is the commit on the master branch
git init
echo "aaa" >f1
git add f1
git commit -m A

# this is the piece of the script that builds the sources branch
git checkout --orphan sources
# git rm --cached ...   remove binaries, if any"
git commit -m A --allow-empty
git rev-list --all --pretty=oneline

When there are binaries in the commit A, they are removed, and the
tree for the second
git commit is then different, and the commit is actually created.
When there are no binaries (as in the script above, in which the
removal is commented out),
the second git commit would not create any new commit, and I would not
have an orphan
branch. Thence the --allow-empty to force it to create a new commit.
Unfortunately, it creates a new commit only if the system clock
changes the seconds of
the system time between the two git commits.
If you insert a "sleep 1" before the second git commit, the commit is
really created.

I spent many hours to spot this time-dependent error ....

-Angelo
--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


-----
No virus found in this message.
Checked by AVG - www.avg.com
Version: 2012.0.2221 / Virus Database: 2441/5305 - Release Date: 10/02/12


--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Index of Archives]     [Linux Kernel Development]     [Gcc Help]     [IETF Annouce]     [DCCP]     [Netdev]     [Networking]     [Security]     [V4L]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux SCSI]     [Fedora Users]