Which is the best way to version control Xilinx PlanAhead projects?
My personal workflow (I mention planAhead, but vivado is similar), with goal to add as little as possible to source-control:


Files exist outside the planAhead project directory. Take care since if you use the GUI to add/create files, it will likely be inside the project directory.
IP cores exists in my source directories, one sub-folder by IP core.
Every HDL source is source-controlled, as well as every .xco/.xci, *.xmp, *.mhs, constraints files, etc
Simulation sources are located in a separate folder than synthesize sources to set up her properties easily.
The planAhead project directory/.ppr is not source controlled.
The IP core/microblaze generated files are not source-controlled. This is up to debate, I think if you add *.ngc, *.vhd, *.v, *.xise you won't have to regenerate the cores every time you checkout from source-control, which can save you a large amount of time. I barely use IP cores at all in my own projects, but if you use a lot you may want to look into this.


Then, I add a script to create the project in source-control:

# Obtain the script directory and pass to a variable
set projDir [file dirname [info script]]
# Change active directory to directory of the script
cd $projDir

# Define directories labels
set hdlDir ./src/hdl
set simDir ./src/sim
set ipsDir ./src/IPs
set conDir ./src/constrs

# Define other labels
set projName projectname
set topName toplevel
set device partname

# Create project in prj directory
create_project -force $projName prj -part $device

# Add simulation files from sim directory and disable synthesis property
# Do it before adding any other source!!
add_files -fileset sim_1 $simDir
set_property used_in_synthesis false [ get_files -of_objects [get_filesets sim_1] -filter {FILE_TYPE == VHDL || FILE_TYPE == Verilog} ]

# Add HDL sources
add_files $hdlDir

# Add IP cores
add_files $ipsDir/ip0/ip0.xco
add_files $ipsDir/ip1/ip1.xco
add_files $ipsDir/mb/system.xmp 

# Add constraints
add_files -fileset constrs_1 $conDir

# Set VHDL libraries
set_property library awesome_lib [get_files $hdlDir/awsome_library/*]

# Set top module
set_property top $topName [current_fileset]

make_wrapper -files [get_files *.xmp] -top -fileset [get_filesets sources_1] -import


If you organize your sources files appropriately, the script should need a minimal amount of lines and not need to change when you add source files. Since the script is in source-control, it should stay in sync anyways (you do have to maintain it, since I expect you will use the GUI in your everyday use).

You should be able to start from there and add what you need. If you are not aware, most of what you do in planAhead GUI is a TCL command. You can see what commands were executed by going File->Open Journal.