There are many ways a variable can be created or changed other than using the set command, really too many to be feasible to attempt to monitor like this. Just some examples:
lassign $foo a b ;# variables a and b set / updated
dict set foo bar baz ;# variable foo set or updated
foreach element $list {} ;# variable element set
dict with foo {} ;# any keys in $foo become variables
And this is not limited to Tcl built-in commands, for example my json command has equivalents to most of the above examples, so unless you prevent new commands being defined by the script you're sourcing it's not even possible to track it by tracing all the known commands that could affect variables.
I'm not sure about the details of your use case, but if it's just global variables I might try something like this:
proc var_changed {v n1 n2 op} {
puts "variable $v $op"
}
set start_vars [info vars]
foreach v $start_vars {
trace add variable $v {write unset} [list var_changed $v]
}
source $other_file
foreach v [info vars] {
if {$v ni $start_vars} {
puts "New var defined: $v"
}
}
While the trace handler is executing, additional traces on the variable that triggered it are suppressed.
This example doesn't handle all the cases that could happen with array variables, or variables that are unset and then later added back. It's possible to extend this technique to variables in namespaces, but it starts to feel fragile and heavy-handed. If your use case is really about containing side-effects by the sourced script with unknown contents, then I'd advise rather sourcing the script in a child interpreter (a safe child if you don't trust the source of the script), maybe like this:
set child [interp create -safe]
$child eval [list set foo $foo] ;# Copy the state of selected variables
$child eval [list set bar $bar] ;# to the child interp
$child eval [list source $other_file]
# Retrieve the state of vars in the child after sourcing $other_file if needed:
puts "foo in child: [$child eval [list set foo]]"
# Clean up
interp delete $child
tracethe variable instead? There are other ways to write to a variable thanset...