difference between "svn update DIR" and "cd DIR && svn update" - linux

What is the difference between running: svn update DIR and running svn update with DIR as cwd? (DIR is my checkout's root).
Intuitively, I'd expect the two to do the same thing, but I noticed that when running the former (when cwd is outside the local checkout), sometimes not all updates are fetched. But then running the latter fetches what it needs to.
(running on linux)
EDIT: to all the skeptics, here's a session I've just had:
$ svn up DIR/
Password for 'xxx': ...
Skipped 'DIR'
$ cd DIR/
$ svn up
Password for 'xxx': ...
U aaa
U bbb
...
U .
Updated to revision 8965.
$

The following is pure wild speculation. I know virtually nothing about svn and nothing about its internals.
That being said I would guess that from outside the checkout svn looks in the current directory for configuration information, doesn't find any, and then does the minimum necessary to update the given directory (by reading its specific configuration information) and that from inside the checkout svn operates in a more recursive/project-aware mode because the local directory contains the configuration it needs.
Examining the operational differences between the two runs with something like strace might provide some clues.
Assuming there is a difference after all and what you are seeing isn't merely later changes getting pulled in by a second update (with an active project for example).

There is no difference. svn update without a target specified simply uses . as the target.
Based on your updated question. There are two ways you get the "Skipped 'DIR/'" message:
You had a path in conflict (either the target or one of it's parents) and you would have had to resolve it between the two commands. Which seems unlikely given your example
You had typoed the path in the svn up command and have the cdspell option turned on in your shell.
Take this for example:
$ ls -d trunk
trunk/
$ svn up truunk/
Skipped 'truunk'
$ cd truunk/
trunk/
$ svn up
At revision 1540579.
If you have a simple reproduction method I'd be interested in it.

Related

SVN: undo a merge with local changes

I was on version 100, with local changes.
I did an svn up to reach HEAD (which is revision 200). Then I was ill adviced to revert back to revision 150, with my local changes, in command: svn merge -r HEAD:150 .
Now I actually want to go back to revision 200 with my local changes. svn up doesn't do anything, because I appear to still have file missings. I know because a file A.cpp was in revision 200 but not in my local working copy.
If I do svn status, I see a bizzare "D" in front of A.cpp. they seem to think I want to delete this file I don't even own.
What state am I in now, and how do I fix it?
In brief, your current checked out repo is messed up - it has a combination of your changes as well as a set of uncommitted changes to go back from HEAD -> r150. If you committed at this point, it would have the effect of removing all the changes that happened from 150:HEAD, and then adding in your changes.
If trying to do a re-merge: svn merge -r 150:HEAD . doesn't work (and generally it won't), then I would suggest the following:
assuming you have your current workspace <currws>
checkout a second copy of the workspace, at revision 150: svn co -r 150 <svn url> <newws>. This will give you a directory <newws>
(cd <currws>; tar cf - --exclude .svn .) | (cd <newws>; tar xf -). This will take all the files & directories from <currws> and copy them into <newws>.
Take inventory of the new directory - it should now contain copies of only your changes - some of these may need to be SVN added to the workspace; or if you have deletes, they will need to be re-deleted on the <newws>. You can pre-remove all the files/folders from new-ws prior to the tar, and anything that appears after the tar with a ! indicates a file that you removed with your changes, anything with a ? is a file that needs adding, and the remainder should be M entries.
Bring the new workspace up to HEAD - svn up <newws> should work in this case.
verify that everything's working and that it only contains your changes.
make a patch file, get it code reviewed and then commit it.
I'm pretty sure this will get you back on-track; although I don't have a tree to check against with the spotty network connectivity I have.

Git: How to list all (staged) files attempting to be committed

Wrote a bash script for the prepare-commit-msg git hook. It lists all staged files that exist, but I only want the staged files that are attempting to be committed (i.e. Example of desired input/output at the bottom of the page).
My script's job is to prevent a commit from happening if the files attempting to be committed did not follow a certain commenting convention (i.e. think java docs). Not only this, but it edits and auto formats the comments to meet my commenting convention. This is extremely important to note because I can't just grab the SHA-1 of the commit because this script needs to happen before that key is ever created.
This works perfectly when I execute commit -a (i.e. commit all files). However, I run into problems when I want to just commit a few of my staged files.
Is there a way I can catch only the staged files that are attempting to be committed, not just every single staged file that exists?
For example, let's say my staged files were the following:
file1.txt
file2.txt
file3.txt
file4.txt
file5.txt
When I execute git commit file1.txt file2.txt file3.txt, I want to catch file1.txt file2.txt file3.txt in my script...but not file4.txt and file5.txt.
Is there anyway to do this?
EDIT: Definitely not a duplicate. The solution to the "duplicate" question is definitely not what I'm asking for.
$ git status -s -uno
M E
A R
The file E is modified, the file R is staged(added).
An unstaged file has the action marker in the second column (after git reset E, to unstage the file E):
$ git status -s -uno
M E
A R
These can be dropped with grep -v '^ ' for example.
Here is a complete proof in my test directory:
Tracked Files
~/test/ed $ git ls-tree HEAD
100644 blob 96bf192a9be8d1cecc314f66bb1ef5961564e983 E
100644 blob 11470e37f3d22a2548ce5c85040a44c9581d7727 I
100644 blob 8f2f9e95d9b00595d1588ccef91495c06295f5fa O
Filesystem Files (all, as in git commit -a)
~/test/ed $ ls -l .
total 16
-rw-r--r-- 1 ingo ingo 140 25. Jun 05:48 E
-rw-r--r-- 1 ingo ingo 143 25. Jun 05:39 I
-rw-r--r-- 1 ingo ingo 106 25. Jun 05:29 O
-rw-r--r-- 1 ingo ingo 157 25. Jun 05:28 R
Status of the working directory: Changes against HEAD and staged files
~/test/ed $ git status -s -uno
M E
A R
The output without the modified files that are not yet or no more (git reset) in the index (aka. not staged or unstaged)
~/test/ed $ git status -s -uno|grep -v '^ '
A R
Staged filenames only, without the operation flag
~/test/ed $ git status -s -uno|grep -v '^ '|awk '{print $2}'
R
Git commit operation, status and control
Git introduces its own terminology. Some of these words have been used in a wrong way, I will describe the misunderstood concepts and the problematic commands that lead to the erroneous formulation.
Luckily git has a very strong, defined language, where each term has an exact meaning, some of them can be seen in git help gitglossary. To understand the concepts git uses, the git help git page is worth to be read 5-50 times together with the introductory pages that are linked from there.
If you installed a git version without the documentation, slap your system administrator. I assume, that most people who actively read questions, answers and articles are there own administrators, so slap yourself, but not too hard ;) Of course the docs can be found on the net, but they are an integral part of a to-be-used git installation.
Luckily git was initiated and its core was completely written by one of the most excellent minds of our days or at least, by one who uses strictest logic concepts, instead of applying killer tools, to write and control his software development: Linus Thorvalds.
That makes it possible to use the same terms with defined meanings, when we talk about git and operations in a git repository. I won't go to deep though, as some of the concepts are developed with quite advanced theoretical terms in computer science in mind.
The git repository
There are two main types of git repositories, called bare and non-bare, or I sometimes say checked-out (git help init). In this article I just talk about non-bare repositories, where the tracked files of the repository live in the working directory
from gitglossary(7):
working tree
The tree of actual checked out files. The working tree normally
contains the contents of the HEAD commit’s tree, plus any local
changes that you have made but not yet committed.
Note for the Noobs: gitglossary(7) means the manual page with the name "gitglossary" in section 7. With man this page can be reached with man -s7 gitglossary. With git help gitglossary exactly the same will show, with git help --web gitglossary you see a well formatted document in your browser, if your system is configured to remote call a html page into your browser session. With Windows, where there is no man you will always be directed into the browser. For git commands such as add the manual page is man 1 git-add or git-add(1).
Tracked Files
We have seen here, that the term tracked means that the git repository knows and controls that file. The glossary does not come from the gitglossary(7), but from git-add(1), option
-u, --update
Update the index just where it already has an entry matching
<pathspec>. This removes as well as modifies index entries to
match the working tree, but adds no new files.
If no <pathspec> is given when -u option is used, all tracked
files in the entire working tree are updated (old versions of
Git used to limit the update to the current directory and
its subdirectories).
The command git add --update is one of the most important operations to understand the handling of in the working tree by git.
Here shows the problem
with git commit file1.txt file2.txt file4.txt, but lets first define some more terms.
Staged Files or Index
The set of staged files build the index (see gitglossary(7) for index, but ignore the several merge levels or the unmerged index). For our purpose
The index is a stored version of your working tree.
namely that stored version of your working tree that is prepared to be committed as one commit (again gitgloassary(7)
commit
`As a noun: A single point in the Git history;
... "revision" or "version" are synonyms from other version control systems. As Git users we say "commit".
... to be continued (26.Friday) ...

SVN not committing, showing files as not under control

Here we can see that SVN is not adding files that need to be added, and not committing:
$ ls -la forum
drwxr-xr-x 6 dotan.cohen coders 4096 Apr 9 02:09 before
$ svn status
? tags
? forum/before
$ svn add forum/before --force
$ svn status
? tags
? forum/before
$ svn commit -m "Some Comment"
$
The first command (ls -la) shows us that forum/before/ is in fact a directory. The next command svn status shows us that the directory is not under version control. The next line (svn add) shows an attempt to add the directory to version control, and the line after it shows that the directory still is not under version control. The last line shows that an svn commit does nothing, i.e. no commit.
I can confirm that the directory in question is not added to the repository. Why might that be, and how can I fix it? This is on CentOS 5. Thanks.
If you ever find yourself in this situation again, I would suggest using svn switch rather than deleting the .svn directories. This will re-point all of the URLs. The general syntax is switch URL[#PEGREV] [PATH].
The problem was that the directory in question was copied from another directory under version control. Removing all the .svn subdirectories resolved the issue. I used the following command to remove them (from within forum/before/):
rm -rf `find . -name .svn`

How to track changes of my Linux distrib with git?

I am experimenting some linux configuration and I want to track my changes? Of course I don't want to to put my whole OS under version control?
Is there a way (with git, mercurial or any VCS) to track the change without storing the whole OS?
This is what I imagine:
I do a kind of git init -> all hashes of all files are stored, but not the content of the files
I make some changes to my file system -> git detect that the hash of this file has changed
I commit -> the content of the file is stored (or even better the original file and the diff are stored! I know, that is impossible... )
Possible? Impossible? Work-arounds?
EDIT: What I care about is just to minimize the size of the repository and to have a repository containing only my changes. Having all files in my repository is not relevant for me. For example if i push to github I just want it to contain only the files that has changed.
Take a look at etckeeper, it will probably do the job.
What you want is git update-index --info-only or ... --index-info, from the man page: " --info-only is used to register files without placing them in the object database. This is useful for status-only repositories.". --index-info is its industrial-scale cousin.
Do that with the files you want to track, write-tree to write the index structure into the object db, commit-tree that, and update-ref to update a branch.
To get the object name use git hash-objectfilename.
Here is what we do...
su -
cd /etc
echo "*.cache" > .gitignore
git init
chmod 700 .git
cd /etc; git add . && git add -u && git commit -m "Daily Commit"
Then setup crontab:
su -
crontab -e
# Put the following in:
0 3 * * * cd /etc; git add . && git add -u && git commit -m "Daily Commit"
Now you will have a nightly commit of all changes in /etc
If you want to track more than /etc in one repo, then you could simply do it at the root of your filesystem, except add the proper ignore paths to your /.gitignore. I am unclear on the effects of having git within git, so you might want to be extra careful in that case.
I know this question is old, but I thought this might help someone. Inspired by #Jonathon's comment on the How to record concrete modification of specific files question, I have created a shell script that enables you to monitors all the changes done on a specific file, while keeping all the changes history. the script depends on the inotifywait and git packages being installed.
You can find the script here
https://github.com/hisham-hassan/linux-file-monitor
Usage: file-monitor.sh [-f|--file] <absolute-file-path> [-m|--monitor|-h|--history]
file-monitor.sh --help
-f,--file <absolute-file-path> Adding a file to the monitored files List. The <absolute-file-path>
is the absolute file path of the file we need to action.
PLEASE NOTE: Relative file path could cause issues in the script,
please make sure to use the abolute path of the file. also try to
avoid sym links, as it has not been tested.
example: file-monitor.sh -f /absolute/path/to/file/test.txt -m
-m, --monitor Monitoring all the changes on the file. the monitoring will keep
happening as long as the script is running; you may need to run it
in the background.
example: file-monitor.sh -f /absolute/path/to/file/test.txt -m
-h, --history showing the full history of the file.
To exit, press "q"
example: file-monitor.sh -f /absolute/path/to/file/test.txt -h
--uninstall uninstalls the script from the bin direcotry,
and removes the monitoring history.
--install Adds the script to the bin directory, and creates
the directories and files needed for monitoring.
--help Prints this help message.

Checking changes made before/after installing application?

On Linux, I need to know which files were added/modified/moved/deleted after compiling and installing an application from source code, ie. the command-line, Linux equivalent to the venerale InCtrl5.
Is there a utility that does this, or a set of commands that I could run and would show me the changes?
Thank you.
Edit: The following commands are sort of OK, but I don't need to know the line numbers on which changes occured or that "./.." were updated:
# ls -aR /tmp > b4.txt
# touch /tmp/test.txt
# ls -aR /tmp > after.txt
# diff -u b4.txt after.txt
If you only need to know which files were touched, then you can use find for this:
touch /tmp/MARK
# install application here
find / -newercm /tmp/MARK
This will show you all files whose contents or metadata have changed since you touched /tmp/MARK (including newly added files).
I would personally use something like Mercurial (version control) to do this.
The main reason, is that it is not only effective but it is also clean, since it will only add a hidden directory to the top of the tree where you want to check these changes.
Let's say that you need to know what files changed in /etc/. So before installation (you need to have mercurial installed) you add the directory to mercurial:
cd /etc
hg init
hg add
hg ci -m "adding all files in /etc/ to track them down"
The above will effectively "add" all the files to track them. To verify nothing has changed:
hg st
Should return no files.
If you (or the installation) modifies a file, you should see something like this:
hg st
M foo.sh
The "M" before the file states the given file was modified.
For new files you would see a ? before the file like:
? bar.sh
After you are done and no longer want Mercurial, simple remove the hidden directory:
cd /etc
rm -rf .hg

Resources